## with lists

I was trying to remember how to use Haskell. This blog post focuses only on `Control.Monad.liftM`

function.

The type of `liftM`

is `(Monad m) => (a1 -> r) -> m a1 -> m r`

which evaluates the second argument with the first argument as if it's in do block.

Let me explain that with the following example. You need the list of the values which each of them are three times bigger than the original list [1, 2, 3]. The most straightforward way in Haskell is to use list comprehension.

```
[ x * 3 | x <- [1, 2, 3]]
```

List Comprehension is just a syntactic sugar of List Monad. The code is equivalent to the following code.

```
do x <- [1, 2, 3]
return $ x * 3
```

Do notation is just a syntactic sugar of List Monad as well.

```
[1, 2, 3] >>= \x -> return (x * 3)
```

You also can make the code simpler with point free style.

```
[1, 2, 3] >>= return . (* 3)
```

Now it's time to use `liftM`

. You can write the code with `liftM`

in the following way.

```
liftM (* 3) [1, 2, 3]
```

This is the simplest. Note that you have to declare `import Control.Monad`

to use `liftM`

.

## with Parsec

The code below is from Write Yourself a Scheme in 48 Hours.

```
parseNumber = liftM (Number . read) $ many1 digit
```

I rewrite it without `liftM`

.

```
parseNumber = do x <- many1 digit
return $ Number $ read x
```

or

```
parseNumber = do x <- many1 digit
return $ (Number . read) x
```

or

```
parseNumber = many1 digit >>= \x -> return $ (Number . read) x
```

or

```
parseNumber = many1 digit >>= \x -> (return . Number . read) x
```

or

```
parseNumber = many1 digit >>= return $ Number . read
```

## summary

Using `liftM`

can make code simpler and easier to understand with its natural order of arguments.

The most difficult thing for using `liftM`

is to write the correct spelling of `liftM`

. I cannot remember how many times I wrote `listM`

instead of `liftM`

. It is very difficult and fatal issue.

Hi, I found this page while trying to understand liftM via the same tutorial. Thanks for your page, I found it very helpful.

ReplyDeleteBut I think perhaps the last example has an error - it doesn't compile as-is. I believe it should read "parseNumber = many1 digit >>= return . Number . read".

Cheers,

John :^P

Oh right, thanks for pointing it out!

ReplyDelete