The Maybe monad
Overview
| Computation type: |
Computations which may return Nothing |
| Binding strategy: |
Nothing values bypass the bound function,
other values are used as inputs to the bound function.
|
| Useful for: |
Building computations from sequences of functions that may return
Nothing. Complex database queries or dictionary lookups
are good examples.
|
| Zero and plus: |
Nothing is the zero. The plus operation returns the
first non-Nothing value or Nothing is both
inputs are Nothing.
|
| Example type: |
Maybe a |
Motivation
The Maybe monad embodies the strategy of combining a chain of computations that
may each return Nothing by ending the chain early if any step
produces Nothing as output. It is useful when a computation
entails a sequence of steps that depend on one another, and in which some
steps may fail to return a value.
If you ever find yourself writing code like this:
case ... of
Nothing -> Nothing
Just x -> case ... of
Nothing -> Nothing
Just y -> ...
you should consider using the monadic properties of Maybe to
improve the code.
Definition
data Maybe a = Nothing | Just a
instance Monad Maybe where
return = Just
fail = Nothing
Nothing >>= f = Nothing
(Just x) >>= f = f x
instance MonadPlus Maybe where
mzero = Nothing
Nothing `mplus` x = x
x `mplus` _ = x
|
Example
A common example is in combining dictionary lookups.
Given a dictionary that maps full names to email
addresses, another that maps nicknames to email addresses,
and a third that maps email addresses to email preferences,
you could create a function that finds a person's email
preferences based on either a full name or a nickname.
| Code available in example11.hs |
data MailPref = HTML | Plain
data MailSystem = ...
getMailPrefs :: MailSystem -> String -> Maybe MailPref
getMailPrefs sys name =
do let nameDB = fullNameDB sys
nickDB = nickNameDB sys
prefDB = prefsDB sys
addr <- (lookup name nameDB) `mplus` (lookup name nickDB)
lookup addr prefDB
|