# Ramblings on monads

April 9, 2012 - Tagged as: haskell, en.

I had written a short post about Haskell and monads to Nathan’s University forum as a first homework, and I wanted to add it to my blog too:

I know lots of people here have already given Haskell as an example, but I want to mention to a different point of Haskell. Monads and DSL capabilities.

Every monad in Haskell is potentially a DSL. You can define commands(ie. functions) in a syntax that looks almost like syntax in imperative languages even if you’re doing a purely functional computation(for imperative computations, see IO monad). When you write a monad and some functions working with this monad, you basically write operations of a kind of computations, and a way to combine this computations(with `>>=` function, read as bind).

This gives you two great advantages. First, monads give you an elegant way to separate combination and calculation logic, and second, it gives you an opportunity to create syntactic abstractions.

For example, you don’t have to pass some states around functions thank to monads. You can just create a monad with functions getting a state and returning some values and the new state. Then you can define your combination logic(bind functions) and with the help of `do` notation, you can write almost imperative looking code, passing states automatically. See example:

``````import Control.Monad.State
import Control.Monad
type AvgState = State (Int, Int) Int
state0 = (0, 0)

addAvg :: Int -> AvgState
addAvg x = do
(count, total) <- get
put (count+1, total+x)
return \$ (total+x) `div` (count+1)

test :: AvgState
test = do
addAvg 10
addAvg 20
addAvg 30

main :: IO ()
main = do
print \$ evalState test state0``````

Here I’m calculating arithmetic average of some integers. `type AvgState` is my data type representing the sum of the numbers I give and the total count of numbers. Here I don’t write a new monad, instead I use Haskell’s State monad, contained in `Control.Monad.State` package.

`addAvg` functions is the main logic. If you look at it, it almost looks like an imperative program, I’m reading some values and changing them by adding them one, and returning a new value(note that I’m not returning any new states, it’s being handled my the monad itself), but still it’s purely functional.

Now how’s that a DSL? Look at `test` function and hopefully you’ll see :) .

I want to give another example about DSL-like monads: `Parsec`.

I’ve been working on a Websocket based chat protocol written in Haskell lately and this code is directly from my project:

``````chanName :: Parser ChanName
chanName = many1 (letter <|> oneOf "-" <|> digit)

msgCmd :: Parser Cmd
msgCmd = do
string "msg"
spaces
chan <- chanName
spaces
msg <- many1 anyChar
eof
return \$ MsgCmd chan msg``````

I’m using Parsec’s `Parser` monads with `do` notation and it looks almost like Backus–Naur Form. chanName mathes list of letters, ‘-’ character, or digits with at least one element. This is a parser. And then I’m using this parser in my `msgCmd` parser. It matches a string “msg”, then arbitrary number of spaces, then `chanName`, then spaces again, and at last any characters.