Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid pattern matching inside a monad in Haskell

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?

like image 413
user1472346 Avatar asked Dec 07 '25 01:12

user1472346


1 Answers

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.

like image 113
nponeccop Avatar answered Dec 08 '25 21:12

nponeccop