Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between liftM and mapM in Haskell

Tags:

What is the difference between the functions liftM and mapM?

like image 838
Luke Avatar asked May 02 '11 11:05

Luke


People also ask

What does mapM do in Haskell?

The core idea is that mapM maps an "action" (ie function of type a -> m b ) over a list and gives you all the results as a m [b] . mapM_ does the same thing, but never collects the results, returning a m () . If you care about the results of your a -> m b function (ie the b s), use mapM .

What does LIFT do in Haskell?

Lifting is a concept which allows you to transform a function into a corresponding function within another (usually more general) setting.

What are monads Haskell?

What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.


1 Answers

They aren't really related. I'll try to explain what each of them does. I assume you have a basic understanding of what a monad is.

liftM :: Monad m => (a -> b) -> (m a -> m b) lets you use an ordinary function in a monad. It takes a function a -> b, and turns it into a function m a -> m b, that does exactly the same thing as the original function, but does it in a monad. The resulting function doesn't "do" anything to the monad (it can't, because the original function didn't know it was in a monad). For example:

main :: IO () main = do     output <- liftM ("Hello, " ++) getLine     putStrLn output 

The function ("Hello, " ++) :: String -> String prepends "Hello, " to a string. Passing it to liftM creates a function of type IO String -> IO String -- now you have a function that works in the IO monad. It doesn't do any IO, but it can take an IO action as input, and produces an IO action as output. Therefore, I can pass getLine as input, and it will call getLine, prepend "Hello, " to the front of the result, and return that as an IO action.

mapM :: Monad m => (a -> m b) -> [a] -> m [b] is quite different; note that unlike liftM, it takes a monadic function. For example, in the IO monad, it has type (a -> IO b) -> [a] -> IO [b]. It is very much like the ordinary map function, only it applies a monadic action to a list, and produces a result list wrapped in a monadic action. For example (a pretty bad one):

main2 :: IO () main2 = do     output <- mapM (putStrLn . show) [1, 2, 3]     putStrLn (show output) 

This prints:

1 2 3 [(),(),()] 

What it is doing is iterating over the list, applying (putStrLn . show) to each element in the list (having the IO effect of printing out each of the numbers), and also transforming the numbers into the () value. The resulting list consists of [(), (), ()] -- the output of putStrLn.

like image 199
mgiuca Avatar answered Sep 28 '22 04:09

mgiuca