3

次の定義があります。

env = DataMap.fromList [
                ("foo",42), ("bar",69),
                ("baz",27), ("qux",0)
               ]


doSomething:: String →  Writer [String] Int
doSomething s = do
            let v = DataMap.lookup s env
            case v of
                Nothing →  fail $  s ++ " not found"
                Just a →  do
                            tell [s ++ " →  " ++ (show a)]
                            return a

このコードで私を本当に悩ませているのは、doSomething 内でのパターン マッチングの使用です。モナドを使用する目的を完全に無効にします。モナドトランスフォーマーを使用せずにモナド関数のみを使用して doSomething 関数を書き直す方法はありますか?

4

2 に答える 2

3

@larsmansが言ったように、最も簡単な方法はmaybe関数を使用することです。

doSomething:: String ->  Writer [String] Int
doSomething s = maybe n (\a -> t a >> return a) $ DataMap.lookup s env where
    n = fail $ s ++ " not found"
    t a = tell [s ++ " ->  " ++ show a]

モナド変換子はここではほとんど役に立ちません。失敗して書き込むいくつかの計算を組み合わせるために1つ必要になります。計算が1つだけの場合は、モナドは必要ありません。

また、の代わりにErrorTトランスフォーマーとthrowError関数を使用してエラーを報告しますfail。エラーを処理するための可能な方法については、 http://www.haskell.org/haskellwiki/Error_reporting_strategiesを参照してください。

于 2012-10-03T14:28:12.000 に答える
0

ややこしいですが、私ならこうします。

doSomething2 :: String -> Writer [String] Int
doSomething2 s =
    maybe (fail $ s ++ " not found") id $ do
       a <- DataMap.lookup s env
       return $ (tell [s ++ " -> " ++ show a] >> return a)
于 2012-10-05T02:11:20.530 に答える