I have the following definitions:
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
What really is annoying me about this code is the use of the pattern matching inside the doSomething. It completely defeats the purpose of using monads. Is there any way of re-writing the doSomething function using only monadic functions without using monad transformers?
As @larsmans said, the easiest way is to use maybe function:
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]
Monad transformers are of little help here. You will need one to combine several calculations which both fail and write. In case of just one calculation you don't need monads.
Also, I'd use ErrorT transformer and throwError function to report error instead of fail. See http://www.haskell.org/haskellwiki/Error_reporting_strategies for possible ways to handle errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With