What is the difference between mapM_ and mapM in Haskell? - haskell

I've already checked Hoogle, http://hackage.haskell.org/package/base-4.7.0.1/docs/Prelude.html#v:mapM, which says that mapM_ ignores the results.
However, I still don't have idea how to use it properly.
main = mapM_ (putStrLn.show) [1,2]
main = mapM (putStrLn.show) [1,2]
main = map (putStrLn.show) [1,2]

mapM_ is useful for executing something only for its side effects. For example, printing a string to standard output doesn't return anything useful - it returns (). If we have a list of three strings, we would end up accumulating a list[(), (), ()]. Building this list has a runtime cost, both in terms of speed and memory usage, so by using mapM_ we can skip this step entirely.
However, sometimes we need to execute side effects and build up a list of the results. If we have a function such as
lookupUserById :: UserId -> IO User
Then we can use this to inflate a list of UserIds to a list of Users:
lookupUsers :: [UserId] -> IO [User]
lookupUsers = mapM lookupUserById

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 bs), use mapM. If you only care about the effect, whatever it is, but not the resulting value, use mapM_ because it can be more efficient and, more importantly, makes your intentions clear.
You would always use mapM_ with functions of the type a -> m (), like print or putStrLn. These functions return () to signify that only the effect matters. If you used mapM, you'd get a list of () (ie [(), (), ()]), which would be completely useless but waste some memory. If you use mapM_, you would just get a (), but it would still print everything.
On the other hand, if you do care about the returned values, use mapM. As a hypothetical example, imagine a function fetchUrl :: Url -> IO Response—chances are, you care about the response you get for each URL. So for this, you'd use mapM to get a lists of responses out that you can then use in the rest of your code.
So: mapM if you care about the results and mapM_ if you don't.
Normal map is something different: it takes a normal function (a -> b) instead of one using a monad (a -> m b). This means that it cannot have any sort of effect besides returning the changed list. You would use it if you want to transform a list using a normal function. map_ doesn't exist because, since you don't have any effects, you always care about the results of using map.

In more general terms, the difference is that mapM_ only needs to "consume" all elements of the input, whereas mapM also needs to "re-build" the data structure, with new values. That's pretty much trivial for lists: you only need to traverse along the cons-cells, updating values with those received from the action you map. But it doesn't work that easily for containers whose structure depends on the actual contained values. So e.g. for Data.Set you can't define the equivalent of mapM with type (a -> m b) -> Set a -> m (Set b) – it is an instance of Foldable, but not of Traversable

mapM_ ignores the result. This means, that no return value will be returned. You can see this in interactive mode:
Prelude> mapM (putStrLn . show) [1,2]
1
2
[(),()]
Prelude> mapM_ (putStrLn . show) [1,2]
1
2

Related

How to return a pure value from a impure method

I know it must sound trivial but I was wondering how you can unwrap a value from a functor and return it as pure value?
I have tried:
f::IO a->a
f x=(x>>=)
f= >>=
What should I place in the right side? I can't use return since it will wrap it back again.
It's a frequently asked question: How do I extract 'the' value from my monad, not only in Haskell, but in other languages as well. I have a theory about why this question keeps popping up, so I'll try to answer according to that; I hope it helps.
Containers of single values
You can think of a functor (and therefore also a monad) as a container of values. This is most palpable with the (redundant) Identity functor:
Prelude Control.Monad.Identity> Identity 42
Identity 42
This is nothing but a wrapper around a value, in this case 42. For this particular container, you can extract the value, because it's guaranteed to be there:
Prelude Control.Monad.Identity> runIdentity $ Identity 42
42
While Identity seems fairly useless, you can find other functors that seem to wrap a single value. In F#, for example, you'll often encounter containers like Async<'a> or Lazy<'a>, which are used to represent asynchronous or lazy computations (Haskell doesn't need the latter, because it's lazy by default).
You'll find lots of other single-value containers in Haskell, such as Sum, Product, Last, First, Max, Min, etc. Common to all of those is that they wrap a single value, which means that you can extract the value.
I think that when people first encounter functors and monads, they tend to think of the concept of a data container in this way: as a container of a single value.
Containers of optional values
Unfortunately, some common monads in Haskell seem to support that idea. For example, Maybe is a data container as well, but one that can contain zero or one value. You can, unfortunately, still extract the value if it's there:
Prelude Data.Maybe> fromJust $ Just 42
42
The problem with this is that fromJust isn't total, so it'll crash if you call it with a Nothing value:
Prelude Data.Maybe> fromJust Nothing
*** Exception: Maybe.fromJust: Nothing
You can see the same sort of problem with Either. Although I'm not aware of a built-in partial function to extract a Right value, you can easily write one with pattern matching (if you ignore the compiler warning):
extractRight :: Either l r -> r
extractRight (Right x) = x
Again, it works in the 'happy path' scenario, but can just as easily crash:
Prelude> extractRight $ Right 42
42
Prelude> extractRight $ Left "foo"
*** Exception: <interactive>:12:1-26: Non-exhaustive patterns in function extractRight
Still, since functions like fromJust exists, I suppose it tricks people new to the concept of functors and monads into thinking about them as data containers from which you can extract a value.
When you encounter something like IO Int for the first time, then, I can understand why you'd be tempted to think of it as a container of a single value. In a sense, it is, but in another sense, it isn't.
Containers of multiple values
Even with lists, you can (attempt to) extract 'the' value from a list:
Prelude> head [42..1337]
42
Still, it could fail:
Prelude> head []
*** Exception: Prelude.head: empty list
At this point, however, it should be clear that attempting to extract 'the' value from any arbitrary functor is nonsense. A list is a functor, but it contains an arbitrary number of values, including zero and infinitely many.
What you can always do, though, is to write functions that take a 'contained' value as input and returns another value as output. Here's an arbitrary example of such a function:
countAndMultiply :: Foldable t => (t a, Int) -> Int
countAndMultiply (xs, factor) = length xs * factor
While you can't 'extract the value' out of a list, you can apply your function to each of the values in a list:
Prelude> fmap countAndMultiply [("foo", 2), ("bar", 3), ("corge", 2)]
[6,9,10]
Since IO is a functor, you can do the same with it as well:
Prelude> foo = return ("foo", 2) :: IO (String, Int)
Prelude> :t foo
foo :: IO (String, Int)
Prelude> fmap countAndMultiply foo
6
The point is that you don't extract a value from a functor, you step into the functor.
Monad
Sometimes, the function you apply to a functor returns a value that's already wrapped in the same data container. As an example, you may have a function that splits a string over a particular character. To keep things simple, let's just look at the built-in function words that splits a string into words:
Prelude> words "foo bar"
["foo","bar"]
If you have a list of strings, and apply words to each, you'll get a nested list:
Prelude> fmap words ["foo bar", "baz qux"]
[["foo","bar"],["baz","qux"]]
The result is a nested data container, in this case a list of lists. You can flatten it with join:
Prelude Control.Monad> join $ fmap words ["foo bar", "baz qux"]
["foo","bar","baz","qux"]
This is the original definition of a monad: it's a functor that you can flatten. In modern Haskell, Monad is defined by bind (>>=), from which one can derive join, but it's also possible to derive >>= from join.
IO as all values
At this point, you may be wondering: what does that have to do with IO? Isn't IO a a container of a single value of the type a?
Not really. One interpretation of IO is that it's a container that holds an arbitrary value of the type a. According to that interpretation, it's analogous to the many-worlds interpretation of quantum mechanics. IO a is the superposition of all possible values of the type a.
In Schrödinger's original thought experiment, the cat in the box is both alive and dead until observed. That's two possible states superimposed. If we think about a variable called catIsAlive, it would be equivalent to the superposition of True and False. So, you can think of IO Bool as a set of possible values {True, False} that will only collapse into a single value when observed.
Likewise, IO Word8 can be interpreted as a superposition of the set of all possible Word8 values, i.e. {0, 1, 2,.. 255}, IO Int as the superposition of all possible Int values, IO String as all possible String values (i.e. an infinite set), and so on.
So how do you observe the value, then?
You don't extract it, you work within the data container. You can, as shown above, fmap and join over it. So, you can write your application as pure functions that you then compose with impure values with fmap, >>=, join, and so on.
It is trivial, so this will be a long answer. In short, the problem lies in the signature, IO a -> a, is not a type properly allowed in Haskell. This really has less to do with IO being a functor than the fact that IO is special.
For some functors you can recover the pure value. For instance a partially applied pair, (,) a, is a functor. We unwrap the value via snd.
snd :: (a,b) -> b
snd (_,b) = b
So this is a functor that we can unwrap to a pure value, but this really has nothing to do with being a functor. It has more to do with pairs belonging to a different Category Theoretic concept, Comonad, with:
extract :: Comonad w => w a -> a
Any Comonad will be a functor for which you can recover the pure value.
Many (non-comonadic) functors have--lets say "evaluators"--which allow something like what is being asked. For instance, we can evaluate a Maybe with maybe :: a -> Maybe a -> a. By providing a default, maybe a has the desired type, Maybe a -> a. Another useful example from State, evalState :: State s a -> s -> a, has its arguments reversed but the concept is the same; given the monad, State s a, and initial state, s, we unwrap the pure value, a.
Finally to the specifics of IO. No "evaluator" for IO is provided in the Haskell language or libraries. We might consider running the program itself an evaluator--much in the same vein of evalState. But if that's a valid conceptual move, then it should only help to convince you that there is no sane way to unwrap from IO--any program written is just the IO a input to its evaluator function.
Instead, what you are forced to do--by design--is to work within the IO monad. For instance, if you have a pure function, f :: a -> b, you apply it within the IO context via, fmap f :: IO a -> IO b
TL;DR You can't get a pure value out of the IO monad. Apply pure functions within the IO context, for instance by fmap

How can I run multiple Haskell IO actions and store the results?

I'm a Haskell beginner, so sorry in advance for the newbie question. I only have a very superficial understanding of monads.
I'm using the function insert from the module Persistent. (I've been following the tutorial here.) It inserts something in a database, and returns the ID. I can use it like this:
resultId <- insert myItem
That works fine for a single item. I can print out the resultId like this:
liftIO $ print resultId
But what if my myItem is actually a list of arbitrary length? I want to map insert over this list, which I can seem to do with:
resultIds <- mapM_ insert myItemList
but then if I try to print out the values:
liftIO $ print resultIds
I just get (). What am I doing wrong?
You are quite close: you need mapM :: Monad m => (a -> m b) -> t a -> m (t b) instead of mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m ()
Like the name and the signature already suggest, both functions take a monadic function and a traversable (let us for now assume that that is a list) of as, and it applies the monadic function to all elements and returns a monadic function that contains a traversable (list) of the results.
So if you write:
resultIds <- mapM insert myItemList
The difference between mapM and mapM_ is that in the case of mapM_ (like the signature already suggests), you are not interested in the outcome, and thus it is not calculated. A reason for this could possibly be that the list is very long (and generated by-need), and thus the list of identifiers would never fit in memory.
then resultIds will contain a list of identifiers.
The explanation about the mapM (and mapM_) function is a bit an oversimplification, but I think that it is usually better to first get more comfortable about monads, than getting details about monadic functions completely right.

Monads return empty type: return ()

type InterpreterMonad = ErrorT String ((StateT (Stack EnvEval)) IO)
argsToContext :: [DefArg] -> [CallArg] -> InterpreterMonad ()
argsToContext xs ys = argsToContext' xs ys Map.empty where
argsToContext' ((ArgForDefinition t name):xs) ((ArgForCall e):ys) m = get >>= \contextStack -> (argsToContext' xs ys (Map.insert name e m ))
argsToContext' [] [] m = get >>= \contextStack -> (put (push contextStack m)) >>= \_ -> return ()
data DefArg =
ArgForDefinition Type VarName
data CallArg =
ArgForCall Evaluable
Hi,
I've got a problem with understanding above piece of Haskell code
Especially, I cannot understand how does it return () and why it is placed here.
Please explain.
return in Haskell does not mean what it means in imperative languages like C or Java. In fact its really the wrong name, but we are stuck with it for historical reasons. Better names would be "pure" or "wrap", meaning that it takes a pure value and wraps it up into the monadic context.
The () type is known as "unit". Its not actually empty because it has one value, also called () (hence the name). However it is sort-of empty because you use it when you don't want to convey any information: there is only one value, so it needs zero bits to represent it. (There is a "Void" type available for when you really don't want it to have any values).
So return () means that this monadic action wraps a unit up in the monadic context. In effect its a no-op: do nothing and return no information.
In this case its being used in the case where the arguments are two empty lists. argsToContext' has the job of pairing up the DefArg list with the CallArg list. The first definition takes the head of each list, does its thing with them, and then calls itself with the tails of each list. When the tails are both empty it calls the second version which puts the resulting context on top of the context stack. If the two lists are of different length then it will throw an exception because neither pattern matches. If its your code then you ought to put in a defensive case, partly to help you debug, partly to show that you actually thought about the case, and partly to stop the compiler nagging you about it.
The 'context' in this case is the interpreter's variables, which are held in the Map. Hence the only effect of argsToContext' is to add these pairs to the context and then return a 'Unit' value. The InterpreterMonad is the monadic type, and the return value has the type InterpreterMonad (), meaning that no information is returned, it just has side effects within the monadic context.
In fact I don't think you need the return () here because put already has type m () for whatever monad you are in. So just delete the >>= \_ -> return () and I think it will work fine.

Define a haskell function [IO a] -> IO[a]

I am doing a haskell exercise, regarding define a function accumulate :: [IO a] -> IO [a]
which performs a sequence of interactions and accumulates their result in a list.
What makes me confused is how to express a list of IO a ? (action:actions)??
how to write recursive codes using IO??
This is my code, but these exists some problem...
accumulate :: [IO a] -> IO [a]
accumulate (action:actions) = do
value <- action
list <- accumulate (action:actions)
return (convert_to_list value list)
convert_to_list:: Num a =>a -> [a]-> [a]
convert_to_list a [] = a:[]
convert_to_list x xs = x:xs
What you are trying to implement is sequence from Control.Monad.
Just to let you find the answer instead of giving it, try searching for [IO a] -> IO [a] on hoogle (there's a Source link on the right hand side of the page when you've chosen a function).
Try to see in your code what happens when list of actions is empty list and see what does sequence do to take care of that.
There is already such function in Control.Monad and it called sequence (no you shouldn't look at it). You should denote the important decision taken during naming of it. Technically [IO a] says nothing about in which order those Monads should be attached to each other, but name sequence puts a meaning of sequential attaching.
As for the solving you problem. I'd suggest to look more at types and took advice of #sacundim. In GHCi (interpreter from Glasgow Haskell Compiler) there is pretty nice way to check type and thus understand expression (:t (:) will return (:) :: a -> [a] -> [a] which should remind you one of you own function but with less restrictive types).
First of all I'd try to see at what you have showed with more simple example.
data MyWrap a = MyWrap a
accumulate :: [MyWrap a] -> MyWrap [a]
accumulate (action:actions) = MyWrap (convert_to_list value values) where
MyWrap value = action -- use the pattern matching to unwrap value from action
-- other variant is:
-- value = case action of
-- MyWrap x -> x
MyWrap values = accumulate (action:actions)
I've made the same mistake that you did on purpose but with small difference (values is a hint). As you probably already have been told you could try to interpret any of you program by trying to inline appropriate functions definitions. I.e. match definitions on the left side of equality sign (=) and replace it with its right side. In your case you have infinite cycle. Try to solve it on this sample or your and I think you'll understand (btw your problem might be just a typo).
Update: Don't be scary when your program will fall in runtime with message about pattern match. Just think of case when you call your function as accumulate []
Possibly you looking for sequence function that maps [m a] -> m [a]?
So the short version of the answer to your question is, there's (almost) nothing wrong with your code.
First of all, it typechecks:
Prelude> let accumulate (action:actions) = do { value <- action ;
list <- accumulate (action:actions) ; return (value:list) }
Prelude> :t accumulate
accumulate :: (Monad m) => [m t] -> m [t]
Why did I use return (value:list) there? Look at your second function, it's just (:). Calling g
g a [] = a:[]
g a xs = a:xs
is the same as calling (:) with the same arguments. This is what's known as "eta reduction": (\x-> g x) === g (read === as "is equivalent").
So now just one problem remains with your code. You've already taken a value value <- action out of the action, so why do you reuse that action in list <- accumulate (action:actions)? Do you really have to? Right now you have, e.g.,
accumulate [a,b,c] ===
do { v1<-a; ls<-accumulate [a,b,c]; return (v1:ls) } ===
do { v1<-a; v2<-a; ls<-accumulate [a,b,c]; return (v1:v2:ls) } ===
do { v1<-a; v2<-a; v3<-a; ls<-accumulate [a,b,c]; return (v1:v2:v3:ls) } ===
.....
One simple fix and you're there.

Create a list using do syntax?

I'm relatively new to Haskell. I'm creating a small api/dsl on top of happstack-lite, which will have an interface more similar to Sinatra, mostly to learn. As a part of this, I want to construct an array using do syntax (basically because it would be prettier than the msum [route, route, route] thing. The usage of the monad would look something like this:
someFunctionThatMakesStrings :: String
unwrapMyMonadAndGiveMeAList :: MyMonad _ -> [String]
makeAList :: [String]
makeAList = unwrapMyMonadAndGiveMeAList do
someFunctionThatMakesStrings
someFunctionThatMakesStrings
someFunctionThatMakesStrings
...
So makeAList would return a list with 3 strings. Notice that I would like to use functions inside it that aren't aware of the monad (they just return a string).
I can do this with Writer, but each function called has to be aware of the Writer monad, and it also seems like overkill (I don't need the return type tuple, and the way I got it to work involved lots of wrapping/unwrapping)
I tried using the list monad itself, but it clearly is intended for something different than this.
So which of my assumptions need to change, and then how would I make a new list-construction monad from scratch? How close can I get?
Writer is definitely what you want here; you can avoid "exposing" Writer to the outside at the cost of a little more overhead in the definitions themselves:
foo :: [String]
foo = execWriter $ do
tell otherList1
tell otherList2
tell otherList3
otherList1 :: [String]
otherList1 = execWriter $ do
...
i.e., you can keep the use of Writer local to each definition, but you have to wrap each list you want to use as a "source" in tell. The key thing here is to use execWriter, which discards the result element of the tuple (it's identical to snd . runWriter).
However, if you have a lot of definitions like this, I would recommend simply using Writer directly, and only applying execWriter in the place where you want the combined result; you can make the types a bit cleaner by defining a synonym like type Foo = Writer [String].
I'm not sure what advantage constructing your own list-creation monad would be; it would end up being identical to Writer [String].
The list monad is indeed irrelevant to what you want to do here.
As far as defining your own list-writing monad goes, it's pretty simple:
data ListWriter a = ListWriter a [String]
runListWriter :: ListWriter a -> (a, [String])
runListWriter (ListWriter a xs) = (a, xs)
execListWriter :: ListWriter a -> [String]
execListWriter = snd . runListWriter
instance Monad ListWriter where
return a = ListWriter a []
ListWriter a xs >>= f = ListWriter b (xs ++ ys)
where ListWriter b ys = f a
The only tricky part is (>>=), where we have to take only the value part of the left argument, feed it into the right hand argument, take it apart, and then combine the two lists inside, wrapping it back up with the result of the right hand side.

Resources