Concept:
Maybe monad
Headline
A monad for dealing with partiality or error handling
Illustration
Let us put to work the Maybe monad in a simple interpreter.
A baseline interpreter
There are these expression forms for floats, addition, and square roots:
-- Simple arithmetic expressions
data Expr = Constant Float | Add Expr Expr | Sqrt Expr
deriving (Eq, Show, Read)
Consider these samples:
-- Sample terms
sample = Sqrt (Constant 4)
sample' = Sqrt (Constant (-1))
The first expression should evaluate to 2.0. Evaluation should somehow fail for the second one. The most straightforward interpreter may be this one:
-- A straightforward interpreter
eval :: Expr -> Float
eval (Constant f) = f
eval (Add e1 e2) = eval e1 + eval e2
eval (Sqrt e) = sqrt (eval e)
Adding error handling to the interpreter
This interpreter would return NaN (not a number) for the second sample. This is suboptimal if we want to represent the error situation explicitly as an error value so that we cannot possibly miss the problem and it is propagated properly. To this end, we may use a Maybe type in the interpreter as follows:
-- An interpreter using a Maybe type for partiality
eval' :: Expr -> Maybe Float
eval' (Constant f) = Just f
eval' (Add e1 e2) =
case eval' e1 of
Nothing -> Nothing
Just f1 ->
case eval' e2 of
Nothing -> Nothing
Just f2 -> Just (f1 + f2)
eval' (Sqrt e) =
case eval' e of
Nothing -> Nothing
Just f -> if f < 0.0
then Nothing
else Just (sqrt f)
Alas, the resulting interpreter is harder to understand. Maybes need to be handled for all subexpressions and the intention of propagating Nothing is expressed time and again.
Monadic style
By conversion to monadic style, we can hide error handling:
-- A monadic style interpreter
evalM :: Expr -> Maybe Float
evalM (Constant f) = return f
evalM (Add e1 e2) =
evalM e1 >>= \f1 ->
evalM e2 >>= \f2 ->
return (f1 + f2)
evalM (Sqrt e) =
evalM e >>= \f ->
guard (f >= 0.0) >>
return (sqrt f)
We can also use do notation:
-- A monadic style interpreter in do notation
evalM' :: Expr -> Maybe Float
evalM' (Constant f) = return f
evalM' (Add e1 e2) = do
f1 <- evalM' e1
f2 <- evalM' e2
return (f1 + f2)
evalM' (Sqrt e) = do
f <- evalM' e
guard (f >= 0.0)
return (sqrt f)
The Maybe monad
The Maybe monad is readily provided by the Haskell library, but we may want to understand how it might have been implemented. The corresponding instance of the type class Monad follows:
-- Monad instance for Maybe
instance Monad Maybe
where
return = Just
Nothing >>= f = Nothing
(Just x) >>= f = f x
The definition of return conveys that a pure computation is successful. The definition of bind conveys that Nothing for the first argument is to be propagated. The Maybe monad actually is a more special monad, i.e., a monad with + and 0:
-- Type class MonadPlus (see Control.Monad)
class Monad m => MonadPlus m
where
mzero :: m a
mplus :: m a -> m a -> m a
-- MonadPlus instance for Maybe
instance MonadPlus Maybe
where
mzero = Nothing
Nothing `mplus` y = y
x `mplus` _ = x
The Haskell library provides the guard function, which we used in the interpreter:
-- Succeed or fail
guard :: MonadPlus m => Bool -> m ()
guard b = if b then return () else mzero
In modern Haskell, we also need to make Maybe an instance of Applicative (for applicative functors and Functor (for functors). This code is omitted here, but see GitHub for this page.
User contributions
User edits
Syntax for editing wiki
For you are available next options:will make text bold.
will make text italic.
will make text underlined.
will make text striked.
will allow you to paste code headline into the page.
will allow you to link into the page.
will allow you to paste code with syntax highlight into the page. You will need to define used programming language.
will allow you to paste image into the page.
is list with bullets.
is list with numbers.
will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.
will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.
will allow your to insert code snippets from @worker.
Syntax for editing wiki
For you are available next options:will make text bold.
will make text italic.
will make text underlined.
will make text striked.
will allow you to paste code headline into the page.
will allow you to link into the page.
will allow you to paste code with syntax highlight into the page. You will need to define used programming language.
will allow you to paste image into the page.
is list with bullets.
is list with numbers.
will allow your to insert slideshare presentation into the page. You need to copy link to presentation and insert it as parameter in this tag.
will allow your to insert youtube video into the page. You need to copy link to youtube page with video and insert it as parameter in this tag.
will allow your to insert code snippets from @worker.