{{ message }}

Instantly share code, notes, and snippets.

Last active Aug 29, 2015

The Monad class defines the basic operations over a monad, a concept from a branch of mathematics known as category theory. From the perspective of a Haskell programmer, however, it is best to think of a monad as an abstract datatype of actions. Haskell's do expressions provide a convenient syntax for writing monadic expressions.

```class Functor f where
fmap :: (a -> b) -> f a -> f b

(>>=)  :: m a -> (a -> m b) -> m b
(>>)   :: m a -> m b -> m b
return :: a -> m a
fail   :: String -> m a```
• `(>>=)` Sequentially compose two actions, passing any value produced by the first as an argument to the second.
• `(>>)` Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such as the semicolon) in imperative languages
• `(return)` Inject a value into the monadic type
• `(fail)` Fail with a message. This operation is not part of the mathematical definition of a monad, but is invoked on pattern-match failure in a do expression.

A minimal complete definition of the Monad class requires implementing `>>=` and `return`, since

```m >> k = m >>= \_ -> k
fail s = error s```

Instances of Functor should satisfy the following laws.

```fmap id  ==  id
fmap (f . g)  ==  fmap f . fmap g```

Instances of Monad should satisfy the following laws.

```return a >>= k  ==  k a
m >>= return  ==  m
m >>= (\x -> k x >>= h)  ==  (m >>= k) >>= h```

`fmap f xs  ==  xs >>= return . f`

### Maybe

The `Maybe` type encapsulates an optional value. The `Maybe` type is a simple kind of error monad where all of the errors are represented by `Nothing`.

```data Maybe a = Nothing | Just a

maybe :: b -> (a -> b) -> Maybe a -> b
maybe n f Nothing  = n
maybe n f (Just x) = f x

instance Functor Maybe where
fmap f Nothing  = Nothing
fmap f (Just x) = Just (f x)

(Just x) >>= k = k x
Nothing  >>= k = Nothing
return         = Just
fail s         = Nothing```

### Lists

```-- not valid Haskell; for illustration only
data [a] = [] | a : [a]

instance Functor [] where
fmap = map

m >>= k = concat (map k m)
return x = [x]
fail s = []```

### IO

A value of type `IO a` is a computation which, when performed, does some I/O before returning a value of type `a`.

The only way to perform an I/O action is to bind it to `Main.main` in your program. It isn't possible to perform I/O from an arbitrary function, unless that function is itself in the `IO` monad and called directly or indirectly from `Main.main`.

```-- abstract
data IO a = ...

instance Functor IO where
fmap f x = x >>= (return . f)

(>>=)  = ...
return = ...
fail s = ioError (userError s)

-- related functions
userError :: String  -> IOError
ioError   :: IOError -> IO a
catch     :: IO a    -> (IOError -> IO a) -> IO a```

The two monadic binding functions, methods in the Monad class, are used to compose a series of I/O operations. The `>>` function is used where the result of the first operation is uninteresting, for example when it is `()`. The `>>=` operation passes the result of the first operation as an argument to the second operation.

As an example of IO usage, the following program reads in an input file, filters out everything that isn't ascii, writes it to an output file, and prints a message that it was successful.

```main = readFile "input-file"                      >>= \s ->
writeFile "output-file" (filter isAscii s) >>
putStrLn "Filtering successful"```

```main = do
writeFile "output-file" (filter isAscii s)
putStrLn "Filtering successful"```

## `do` notation

A do expression provides a more conventional syntax for monadic programming. It allows an expression such as

```putStr "x: "     >>
getLine          >>= \l ->
return (words l)```

to be written in a more traditional way as:

```do putStr "x: "
l <- getLine
return (words l)```

It can also be written using semicolons as follows

`do { putStr "x: "; l <- getLine; return (words l) }`

`mapM f` is equivalent to `sequence . map f`

`mapM      :: Monad m => (a -> m b) -> [a] -> m [b]`

`mapM_ f` is equivalent to `sequence_ . map f`

`mapM_     :: Monad m => (a -> m b) -> [a] -> m ()`

`forM` is `mapM` with its arguments flipped

`forM      :: Monad m => [a] -> (a -> m b) -> m [b]`

`forM_` is `mapM_` with its arguments flipped

`forM_     :: Monad m => [a] -> (a -> m b) -> m ()`

Evaluate each action in the sequence from left to right, and collect the results

`sequence  :: Monad m => [m a] -> m [a]`

Evaluate each action in the sequence from left to right, and ignore the results

`sequence_ :: Monad m => [m a] -> m ()`

Same as `>>=`, but with the arguments interchanged

`(=<<)     :: Monad m => (a -> m b) -> m a -> m b`

`(>=>)     :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c`

Right-to-left Kleisli composition of monads. `(>=>)` with the arguments flipped

`(<=<)     :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c`

`forever act` repeats the action indefinitiely

`forever   :: Monad m => m a -> m b`

`void value` discards or ignores the result of evaluation, such as the return value of an `IO` action

`void      :: Functor f => f a -> f ()`