Confusion about return function and Monad - haskell

Sorry, I am a newbie to Haskell. This questions may be very easy...
From Hoogle, return signature is return :: Monad m => a -> m a
and head signature is head :: [a] -> a
Before I did this head $ return [1,2,3], I thought that ghci would throw errors because m [a] is not the same [a]. But to my surprise, it returned [1,2,3]. And tail $ return [1,2,3] returned []. Why?
One more question:
I wrote a function to generate random number:
drawFloat :: Float -> Float -> IO Float
drawFloat x y = getStdRandom (randomR (x,y))
randList = mapM (const $ drawFloat 2 10) [1..10] -- generate a list of random numbers
When I want to get the head of the list, I first tried head randList (failed) but head <$> randList worked. What is <$>? Can someone explain? Thanks!

I thought that ghci would throw errors because m [a] is not the same as [a].
Maybe not, but m [a] and [b] can unify! For example, we can set m ~ [] and b ~ [a] so that m [a] ~ [] [a] ~ [[a]] and [b] ~ [[a]]. Then we just need to check that [] is a Monad, which it is. And this is just what's happening:
> return [1,2,3] :: [[Int]]
[[1,2,3]]
Then it should be clear why head returns [1,2,3] and tail returns [].
randList = mapM (const $ drawFloat 2 10) [1..n]
As a comment, not answering your question yet: this is better spelled replicateM n (drawFloat 2 10).
head randList (failed) but head <$> randList worked. What is <$>?
The problem here is that head is still expecting a list. Before, when you were using return, the monad hadn't been chosen yet, and so it could be chosen to be []; but here, it's clear that the monad you're using is IO. So head can't make progress. The solution is to teach head how to handle IO. There are many ways, and <$> is one of them; it has this type:
> :t (<$>)
(<$>) :: Functor f => (a -> b) -> f a -> f b
The way to read this is: given a pure function, teach it how to handle IO (or any other kind of effect that qualifies as a Functor). For example, it also has this type:
(<$>) :: ([a] -> a) -> IO [a] -> IO a
There are several other kinds of teachers. Two commonly used ones are <*> and =<<:
Prelude Control.Applicative> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude Control.Applicative> :t (=<<)
(=<<) :: Monad m => (a -> m b) -> m a -> m b
Read the first as: given an effectful computation that produces a pure function, produce a function that can handle effects. The second should be read as: given a function which has some effects before it produces its output, produce a function which can handle effects.
At this point, if these explanations aren't helpful, you should turn to one of the many excellent monad tutorials available elsewhere on the web. My personal favorites are You Could Have Invented Monads! and All About Monads.

Regarding your first question:
return takes a "raw" value and gives you a monad with the value "wrapped" in it. Since you are using head and tail on return [1,2,3] , the monad in question is the list monad []. So in this context,
return [1,2,3] == [[1,2,3]]
apply head and tail on it, you will get [1,2,3] and [], respectively.
On the second question, note that the type of randList is IO [Float]. So it's not a list any more, but a list inside a monad. To apply any function to the content of the monad, you can use fmap (<$> is its infix shorthand), which has the type:
fmap :: Functor f => (a -> b) -> f a -> f b
A monad is always a Functor. So what fmap does, is that it takes an ordinary function, (head in your example), and a monadic value, applies the function to the "content" of the monad, and returns a return-value of the function wrapped in the same monad f.

Related

Can I say that Monad makes it possible to see some types as isomorphic?

Monad can pass Just [1,2], which is a different type from what the original length function takes, to >>= return . length.
Just [1,2] >>= return . length
Can I say that Monad makes it possible to see Maybe [a] as isomorphic with [a] on length using (>>=, return)? (Of course they are not really isomorphic.)
Can I choose the term "isomorphic" this situation?
What your example ultimately illustrates is that Maybe is a functor: if you have some f :: a -> b, you can use fmap to turn it into fmap f :: Maybe a -> Maybe b in a way that preserves identities and composition. Monads are functors, with \f m -> m >>= return . f being the same as fmap f m. In your case, we have the length function being transformed by the Maybe functor.
can I choose term "isomorphic" this situation?
Not really. fmap for Maybe is not an isomorphism. An isomorphism requires there being a two-sided inverse that undoes it, which in this case would be something like:
unFmapMaybe :: (Maybe a -> Maybe b) -> (a -> b)
-- For it to be a two-sided inverse to `fmap`, we should have:
unFmapMaybe . fmap = id
fmap . unFmapMaybe = id
However, there are no (Maybe a -> Maybe b) -> (a -> b) functions, as there is no way to obtain a b result if the input Maybe a -> Maybe b function gives out a Nothing. While there are specific functors whose fmap is an isomorphism (Identity is one example), that is not the case in general.
[a] is isomorphic to the quotient type of Maybe [a] with Nothing and Just [] considered equivalent. Alternatively it is isomorphic to Maybe (NonEmpty a), which simply eliminates the Just [] case.
In other words, [a] can be factorized as a composition of the Maybe and NonEmpty functors.
A result of this is that you can lift any function on NonEmpty a to a function on [a]:
liftEmptyable :: (NonEmpty a -> r) -> [a] -> Maybe r
liftEmptyable _ [] = Nothing
liftEmptyable f (x:xs) = Just $ f (x:|xs)
Not sure that actually has much to do with your question though. As duplode answered, you don't really do anything but a simple functor mapping. We could at most elaborate that the monad laws ensure that the fmap really behaves as if length acted directly on the contained list:
Just [1,2] >>= return . length
≡ return [1,2] >>= return . length -- def. of `Monad Maybe`
≡ return (length [1,2]) -- left-identity monad law

Applying a function that returns a Monad type to a list using the map function

Say I want to apply a simple function (\x -> x+1) to all elements in the list [1,2,3].
I do map (\x -> x+1) [1,2,3]
and get as expected [2,3,4]. The return type is Num a => [a].
Now what happens if my function is returning a Monad type and is defined as \x -> do return x+1?
I want to apply this function somehow to all elements in the list and get back a type (Monad m, Num a) => m [a].
And the value will be the same [2,3,4], just wrapped with a Monad.
I've been struggling with this for a while without much progress. Any idea how can I map this function to my list?
You're looking for mapM. You can find it using Hoogle and just typing in
Monad m => (a -> m b) -> [a] -> m [b]
You'll find it in the first few results. The only difference in the type signature is that it's generalized to Traversable:
mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b)
With it, you can do things like
> mapM (Just . (+) 1) [1,2,3]
> Just [2,3,4]
Or, a bit less trivial:
> mapM (\x -> if x < 5 then Just x else Nothing) [1..10]
> Nothing
There is a monadic version of map - called mapM:
mapM (\x -> return (x+1)) [1,2,3]

What's the monad being used with =<< in this function?

The very first 1-Haskell-a-Day exercise confuses me to a point of no return.
The objective is to filter out elements of a list unless it's equal to the one following. E.g.
> filterByPair [1, 2, 2, 2, 3, 3, 4]
[2,2,3]
(I was trying to make two offset lists, zip them into tuples and remove the tuples that didn't have the same number both times, e.g. [(2,2),(2,2),(3,3)], etc.)
But the mind-blowingly simple solution uses the =<< binding operator:
filterByPair :: Eq a => [a] -> [a]
filterByPair = (init =<<) . group
I'm having trouble figuring that operator out. I don't get the same results in ghci when I try to use it:
> init =<< [2,3,4]
No instance for (Num [b0]) arising from the literal `2'
I find that in ghci I can use, say, replicate with =<<. It seems to be feeding each element of the list into the function:
> replicate 2 =<< [2,3,4]
[2,2,3,3,4,4]
So the first go-around is equivalent to:
> replicate 2 2
[2,2]
It somehow knows to put the list in the second argument of replicate, not the first, and to output them all in one big list rather than separate ones, like fmap does:
> fmap (replicate 2) [2,3,4]
[[2,2],[3,3],[4,4]]
I've read that the binding operator is defined by the monad being used. It's a monad function isn't it? Where's the monad with filterByPair? Does it have something to do with the Eq typeclass in its signature?
Likewise, if I use =<< on its own in ghci, what monad is being used there?
First, filterPairs rewritten into pointful form for clarity:
filterPairs xs = group xs >>= init
We'll be able to get a good idea what's happening from the types alone.
xs :: Eq a => [a]
group :: Eq a => [a] -> [[a]]
init :: [a] -> [a]
(>>=) :: Monad m => m a -> (a -> m b) -> m b
The first argument to (>>=) is group xs :: [[s]], so if we substitute m ~ [] and a ~ [s] in (>>=) we'll get
(>>=) :: [[a]] -> ([a] -> [s]) -> [s]
So we're using the Monad instance of [] here, which is equivalent to concatMap (check the types!). Now we can rewrite filterPairs again
filterPairs xs = concatMap init (group xs)
Now if you figure out how concatMap, init and group work, you should be able to figure how the original filterPairs works.

Multiplying the value within two "Maybe" monads?

I'm currently in the process of trying to learn Haskell, and ran into an odd issue regarding the Maybe monad which I can't seem to figure out.
As an experiment, I'm currently trying to take a string, convert each letter to an arbitrary number, and multiply/combine them together. Here's what I have so far:
lookupTable :: [(Char, Int)]
lookupTable = [('A', 1), ('B', 4), ('C', -6)]
strToInts :: String -> [Maybe Int]
strToInts = map lookupChar
where
lookupChar :: Char -> Maybe Int
lookupChar c = lookup c lookupTable
-- Currently fails
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
test seq = [ x * y | (x, y) <- zip seq $ tail seq, x < y ]
main :: IO ()
main = do
putStrLn $ show $ test $ strToInts "ABC"
When I try running this, it returns the following error:
test.hs:13:16:
Could not deduce (Num (Maybe n)) arising from a use of `*'
from the context (Num n, Ord n)
bound by the type signature for
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
at test.hs:12:9-48
Possible fix: add an instance declaration for (Num (Maybe n))
In the expression: x * y
In the expression: [x * y | (x, y) <- zip seq $ tail seq]
In an equation for `test':
test seq = [x * y | (x, y) <- zip seq $ tail seq]
I'm not 100% sure why this error is occurring, or what it exactly means, though I suspect it might be because I'm trying to multiply two Maybe monads together -- if I change the definition of test to the following, the program compiles and runs fine:
test :: (Num n, Ord n) => [Maybe n] -> [Maybe n]
test seq = [ x | (x, y) <- zip seq $ tail seq, x < y ]
I also tried changing the type declaration to the below, but that didn't work either.
test :: (Num n, Ord n) => [Maybe n] -> [Num (Maybe n)]
I'm not really sure how to go about fixing this error. I'm fairly new to Haskell, so it might just be something really simple that I'm missing, or that I've structured everything completely wrong, but this is stumping me. What am I doing wrong?
Maybe does not have a num instance so you cannot multiply them together directly. You need to somehow apply the pure function to the values inside the context. This is exactly what applicative functors are for!
Applicative functors live in Control.Applicative:
import Control.Applicative
So you have this function and you want to apply it to 2 arguments in a context:
(*) :: Num a => a -> a -> a
You probably learned about fmap, it takes a function and applies it to a value in a context. <$> is an alias for fmap. When we fmap the pure function over the maybe value we get the following result:
(*) <$> Just 5 :: Num a => Maybe (a -> a)
So now we have maybe a function and we need to apply it to maybe a value, this is exactly what the applicative functor does. Its main operator is <*> which has the signature:
(<*>) :: f (a -> b) -> f a -> f b
When we specialize it we get the function we need:
(<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
We apply it and the output is the number you expect.
(*) <$> Just 5 <*> Just 5 :: Num a => Maybe a
So to make your code compile you need to change your test function to use <$> and <*>, see if you can figure out how.
Reite's answer is correct, and it's generally how I'd normally recommend handling it - however, it seems to me that you don't quite understand how to work with Maybe values; if so there is little sense looking at applicative functors right now.
The definition of Maybe is basically just
data Maybe a = Nothing | Just a
Which basically means exactly what it sounds like when you read it in plain english "A value of type Maybe a is either the value Nothing for that type, or a value of the form Just a".
Now you can use pattern matching to work with that, with the example of lists:
maybeReverse :: Maybe [a] -> Maybe [a]
maybeReverse Nothing = Nothing
maybeReverse (Just xs) = Just $ reverse xs
Which basically means "If the value is Nothing, then there's nothing to reverse, so the result is Nothing again. If the value is Just xs then we can reverse xs and wrap it with Just again to turn it into a Maybe [a] value).
Of course writing functions like this for every single function we ever want to use with a Maybe value would be tedious; So higher order functions to the rescue! The observation here is that in maybeReverse we didn't do all that much with reverse, we just applied it to the contained value and wrapped the result of that in Just.
So we can write a function called liftToMaybe that does this for us:
liftToMaybe :: (a->b) -> Maybe a -> Maybe b
liftToMaybe f Nothing = Nothing
liftToMaybe f (Just a) = Just $ f a
A further observation we can make is that because functions are values, we can also have Maybe values of functions. To do anything useful with those we could again unwrap them... or notice we're in the same situation as in the last paragraph, and immediately notice that we don't really care what function exactly is in that Maybe value and just write the abstraction directly:
maybeApply :: Maybe (a->b) -> Maybe a -> Maybe b
maybeApply Nothing _ = Nothing
maybeApply _ Nothing = Nothing
maybeApply (Just f) (Just a) = Just $ f a
Which, using our liftToMaybe function above, we can simplify a bit:
maybeApply :: Maybe (a->b) -> Maybe a -> Maybe b
maybeApply Nothing _ = Nothing
maybeApply (Just f) x = liftToMaybe f x
The <$> and <*> operators in Reite's answer are basically just infix names for liftToMaybe (which is also known as fmap) and maybeApply respectively; They have the types
(<$>) :: Functor f => (a->b) -> f a -> f b
(<*>) :: Applicative f => f (a->b) -> f a -> f b
You don't really need to know what the Functor and Applicative things are right now (although you should look into them at some point; They're basically generalizations of the above Maybe functions for other kinds of "context") - basically, just replace f with Maybe and you'll see that these are basically the same functions we've talked about earlier.
Now, I leave applying this to your original problem of multiplication to you (although the other answers kinda spoil it).
You are correct, the problem is that you are trying to multiply two Maybe values together, but (*) only works in instances of Num.
As it turn out, Maybe is an instance of the Applicative typeclass. This means that you can "lift" funcions that work with a type a to functions that work with a type Maybe a.
import Control.Applicative
Two functions provided by Applicative are:
pure :: a -> f a Puts a pure value in a "neutral context". For Maybe, this is Just.
(<*>) :: f (a -> b) -> f a -> f b Lets you apply a "function in a context" to two "values in a context".
So, suppose we have this pure computation:
(*) 2 3
Here are some analogous computations in a Maybe context:
Just (*) <*> Just 2 <*> Just 3
-- result is Just 6
pure (*) <*> pure 2 <*> pure 3
-- result is Just 6 -- equivalent to the above
pure (*) <*> pure 2 <*> Nothing
-- Nothing
Nothing <*> pure 2 <*> Just 3
-- Nothing
Nothing <*> Nothing <*> Nothing
-- Nothing
If the function or one of the argument is "missing", we return Nothing.
(<*>) is the explicit application operator when working with applicatives (instead of using a blank space, as when we work with pure values).
It's instructive to explore what (<*>) does with other instances of Applicative, like []:
ghci> [succ,pred] <*> pure 3
[4,2]
ghci> [succ,pred] <*> [3]
[4,2]
ghci> pure succ <*> [2,5]
[3,6]
ghci> [succ] <*> [2,5]
[3,6]
ghci> [(+),(*)] <*> pure 2 <*> pure 3
[5,6]
ghci> [(+),(*)] <*> [2,1] <*> pure 3
[5,4,6,3]
ghci> [(+),(*)] <*> [2,1] <*> [3,7]
[5,9,4,8,6,14,3,7]

Haskell : concat two IO Strings

Today I have tried to concat two IO Strings and couldn't get it work.
So, the problem is: suppose we have s1 :: IO String and s2 :: IO String. How to implement function (+++) :: IO String -> IO String -> IO String, which works exactly as (++) :: [a] -> [a] -> [a] but for IO String?
And more general question is how to implement more general function (+++) :: IO a -> IO a -> IO a? Or maybe even more general?
You can use liftM2 from Control.Monad:
liftM2 :: Monad m => (a -> b -> c) -> m a -> m b -> m c
> :t liftM2 (++)
liftM2 (++) :: Monad m => m [a] -> m [a] -> m [a]
Alternatively, you could use do notation:
(+++) :: Monad m => m [a] -> m [a] -> m [a]
ms1 +++ ms2 = do
s1 <- ms1
s2 <- ms2
return $ s1 ++ s2
Both of these are equivalent. In fact, the definition for liftM2 is implemented as
liftM2 :: Monad m => (a -> b -> c) -> m a -> m b -> m c
liftM2 f m1 m2 = do
val1 <- m1
val2 <- m2
return $ f val1 val2
Very simple! All it does is extract the values from two monadic actions and apply a function of 2 arguments to them. This goes with the function liftM which performs this operation for a function of only one argument. Alternatively, as pointed out by others, you can use IO's Applicative instance in Control.Applicative and use the similar liftA2 function.
You might notice that generic Applicatives have similar behavior to generic Monads in certain contexts, and the reason for this is because they're mathematically very similar. In fact, for every Monad, you can make an Applicative out of it. Consequently, you can also make a Functor out of every Applicative. There are a lot of people excited about the Functor-Applicative-Monad proposal that's been around for a while, and is finally going to be implemented in an upcoming version of GHC. They make a very natural hierarchy of Functor > Applicative > Monad.
import Control.Applicative (liftA2)
(+++) :: Applicative f => f [a] -> f [a] -> f [a]
(+++) = liftA2 (++)
Now in GHCI
>> getLine +++ getLine
Hello <ENTER>
World!<ENTER>
Hello World!
(++) <$> pure "stringOne" <*> pure "stringTwo"
implement function (+++) ... which works exactly as (++) :: [a] -> [a] -> [a] but for IO String?
Don't do that, it's a bad idea. Concatenating strings is a purely functional operation, there's no reason to have it in the IO monad. Except at the place where you need the result – which would be somewhere in the middle of some other IO I suppose. Well, then just use do-notation to bind the read strings to variable names, and use ordinary (++) on them!
do
print "Now start obtaining strings..."
somePreliminaryActions
someMoreIOStuff
s1 <- getS1
s2 <- getS2
yetMoreIO
useConcat'dStrings (s1 ++ s2)
print "Done."
It's ok to make that more compact by writing s12 <- liftA2 (++) getS1 getS2. But I'd do that right in place, not define it seperately.
For longer operations you may of course want to define a seperate named action, but it should be a somehow meaningful one.
You shouldn't think of IO String objects as "IO-strings". They aren't, just as [Int] aren't "list-integers". An object of type IO String is an action which, when incurred, can supply a String object in the IO monad. It is not a string itself.

Resources