Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does liftM (:[]) work

Tags:

haskell

I am trying to understand the expression below. It converts the list of characters ['a','b','c'] to a list of strings ["a", "b", "c"]

liftM (:[]) "abc"

How does this happen?

like image 981
akonsu Avatar asked Aug 01 '15 15:08

akonsu


2 Answers

The robotic monkey head operator (:[]) is just the section of the list cons (:) and the empty list [], i.e. (:[]) is equivalent to (\x -> x:[]); which in turn can also be written using list syntax as (\x -> [x]).

Rewritten this way, we have

liftM (\x -> [x]) "abc"

The string literal "abc" is also just syntax sugar for the character list ['a', 'b', 'c'], so we can in turn rewrite the above as

liftM (\x -> [x]) ['a', 'b', 'c']

liftM is just fmap from the Dark Days when Functor wasn't a superclass of Monad, giving

fmap (\x -> [x]) ['a', 'b', 'c']

The Functor instance of [] sets fmap = map, giving

map (\x -> [x]) ['a', 'b', 'c']

which reduces to

[['a'], ['b'], ['c']]

Or, going back to string notation

["a", "b", "c"]

Q.e.d.

like image 151
Cactus Avatar answered Jan 01 '23 06:01

Cactus


Function liftM turns a function which takes input and produces output to a function which takes input in some monad and produces output in the same monad. Lets look at its definition:

liftM :: Monad m => (a -> b) -> m a -> m b
liftM f mx = mx >>= \x -> return (f x)

Strings in Haskell are lists of characters (type String = [Char]), so

"abc" = ['a', 'b', 'c'] :: [Char]

From your application compiler infers a = Char, b = [Char], m a = [Char], m = []. So m b = [[Char]] = [String]. List is a monad where return x = [x] and (>>=) = concatMap. So if we specialize above definition we get:

liftM f mx = concatMap (\x -> [f x]) mx

And if we apply the arguments we get:

concatMap (\x -> [[x]]) ['a', 'b', 'c'] =
concat $ map (\x -> [[x]]) ['a', 'b', 'c'] =
concat $ [[['a']], [['b']], [['c']]] =
[['a'], ['b'], ['c']] =
["a", "b", "c"]
like image 37
aemxdp Avatar answered Jan 01 '23 07:01

aemxdp