Haskell. Why it is working? (Iteration over Monad) - haskell

liftMM :: Monad m => (a -> b) -> m a -> m b
liftMM f m = m >>= \a -> return (f a)
I run:
> liftMM (*2) [1..10]
I got output:
> [2,4,6,8,10,12,14,16,18,20]
I can not see how this function is mapping over all list's values? There is no any recursion or iteration, just one pass monad internal m value to the function f. What I am missing here?

m here is [] and liftMM works by delegating to the implementation of (>>=) and return for m. Therefore you need to understand (>>=) and return for lists, and if you look at the definition they are:
instance Monad [] where
xs >>= f = [y | x <- xs, y <- f x]
return x = [x]
so for each element in the source list >>= applies f and then inserts each element of the returned list into the result list.
return x simply returns a singleton list containing x so return (f a) returns a list [f a]. Each of these single element lists are then combined by (>>=) to create the output list.

A list is a monad, so given the signature for map:
map :: (a->b) -> [a] -> [b]
and the signature for liftMM
liftMM :: Monad m => (a -> b) -> m a -> m b
the [] is the m
This means that for lists liftMM and map do the same thing.

Related

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]

Behavior of reverse >>= (==)

A function for determine if a string is a palindrome can be implemented in a pointfree applicative manner via
pal1 = (==) <$> reverse <*> id
And here is a monadic version
reverse >>= (==)
How does the modadic version work with no explicit call to id? I attempted to view the poinful representation using pointful and get back the same function.
This works using the fact that x -> y can be regarded as a kind of "reader monad". If we were to say
type Reader r x = r -> x
then we have an instance of Monad (Reader r). So we can see that
reverse :: [x] -> [x]
is actually
reverse :: Reader [x] [x]
Similarly,
(==) :: [x] -> [x] -> Bool
can be written as
(==) :: [x] -> Reader [x] Bool
Then (>>=) joins the two together.
So... We start with reverse, which is a Reader action that reads a list and returns a list. We then use >>= to pass that to ==, which is a function that takes a list, and returns a Reader [x] Bool.
In short, the input list is duplicated by the action of Reader, which basically takes an input and passes it to every function in the chain. (That's what the reader monad is.)
I hope that made some kind of sense... It took me a while to figure out!
Let's have a look at the Monad instance for ((->) r):
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
and then simply fill in your monadic code:
reverse >>= (==) = \r -> (==) (reverse r) r
which we can write in a more familiar way:
\r -> reverse r == r
To add to other answers, here is another POV on this. Let's take a definition of bind via fmap and join:
m >>= act = join (fmap act m)
The expression (==) <$> reverse has type Eq a => [a] -> [a] -> Bool and is equivalent to fmap (==) reverse. Now, we pass it to join :: m (m a) -> m a and for (->) r monad instance the type would be ([a] -> [a] -> Bool) -> ([a] -> Bool). That is, join is exactly <*> id part.
I think the easiest way to understand this is by looking at the types:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
specialized to the ((->) r) instance:
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
You are not given an a. The only way to produce one is to apply the first function r -> a to the r you are given. The only way to produce a b is to apply the second function to the r and the a you just produced. This means the only possible definition for this function* is:
f >>= g = \a -> g (f a) a
Plugging our arguments in, we get:
reverse >>= (==)
-- definition of (>>=)
= \a -> (==) (reverse a) a
-- prefix to infix
= \a -> reverse a == a
Parametricity is a powerful tool for reasoning about polymorphic functions.
* other than bottom
The other answers confirm that the two behave the same, but don't explain where the id actually went. In this answer, I will attempt to do so. The punchline is that, for Reader, we have a curious id-removing equation: id >>= return . f = f. (A more beautiful form of this equation is that (id >>=) = (>>= id); together with the monad laws the beautiful form implies the easily-usable form.) To make the explanation a bit simpler, instead of trying to convert from applicative form to monadic form, I will just take it for granted that you believe the following equation:
(==) <$> reverse <*> id
= { too annoying to do carefully }
reverse >>= \xs -> id >>= \ys -> return ((==) xs ys)
So we will start from that last line, and end at reverse >>= (==). Along the way, it will be key to observe that id is the identity for (.) -- which just so happens to be fmap for the Reader monad. Here we go:
reverse >>= \xs -> id >>= \ys -> return ((==) xs ys)
= { monad law }
reverse >>= \xs -> fmap ((==) xs) id
= { definition of fmap for Reader }
reverse >>= \xs -> (.) ((==) xs) id
= { id is the identity of fmap }
reverse >>= \xs -> (==) xs
= { eta reduction }
reverse >>= (==)
So what is the meaning of id >>= return . f = f? Well, treating functions as "indexed values", we can understand id as being the value that equals its index; and return as being the value that is the same everywhere. So id >>= return . f says "look at index x; then, (still at index x), return the value that ignores its index and has value f x". It just so happens that the index we ignore and the value we hand to f match up -- so we might as well skip all that indirection and simply say "look at index x and apply f to it". This is the meaning of the equation.

Understanding "Monad m" in >>=

Looking at Haskell's bind:
Prelude> :t (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
I was confused by the following example:
Prelude> let same x = x
Prelude> [[1]] >>= \x -> same x
[1]
Looking at >>='s signature, how does \x -> same x type check with a -> m b?
I would've expected \x -> same x to have produced a [b] type, since the Monad m type here is [], as I understand.
You say
I would've expected \x -> same x to have produced a [b] type, since the Monad m type here is [], as I understand.
and so it does because it is.
We have
[[1]] >>= \ x -> same x
=
[[1]] >>= \ x -> x
[[Int]] [Int] -> [Int] :: [Int]
[] [Int] [Int] -> [] Int :: [] Int
m a a m b m b
Sometimes [] is describing a kind of "nondeterminism" effect. Other times, [] is describing a container-like data structure. The fact that it's difficult to tell the difference between which of these two purposes is being served is a feature of which some people are terribly proud. I'm not ready to agree with them, but I see what they're doing.
Looking at >>='s signature, how does \x -> same x type check with a -> m b?
It's actually very simple. Look at the type signatures:
same :: x -> x
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(>>= same) :: Monad m => m a -> (a -> m b) -> m b
|________|
|
x -> x
Therefore:
x := a
-- and
x := m b
-- and by transitivity
a := x := m b
-- or
a := m b
Hence:
(>>= same) :: Monad m => m (m b) -> m b
This is just the join function from the Control.Monad module, and for the list monad it is the same as the concat function. Thus:
[[1]] >>= \x -> same x
-- is the same as the following via eta reduction
[[1]] >>= same
-- is the same as
(>>= same) [[1]]
-- is the same as
join [[1]]
-- is the same as
concat [[1]]
-- evaluates to
[1]
I would've expected \x -> same x to have produced a [b] type, since the Monad m type here is [], as I understand.
Indeed, it does. The \x -> same x function which has the type x -> x is specialized to the type [b] -> [b] as I explained above. Hence, (>>= same) is of the type [[b]] -> [b] which is the same as the concat function. It flattens a list of lists.
The concat function is a specialization of the join function which flattens a nested monad.
It should be noted that a monad can be defined in terms of either >>= or fmap and join. To quote Wikipedia:
Although Haskell defines monads in terms of the return and >>= functions, it is also possible to define a monad in terms of return and two other operations, join and fmap. This formulation fits more closely with the original definition of monads in category theory. The fmap operation, with type Monad m => (a -> b) -> m a -> m b, takes a function between two types and produces a function that does the “same thing” to values in the monad. The join operation, with type Monad m => m (m a) -> m a, “flattens” two layers of monadic information into one.
The two formulations are related as follows:
fmap f m = m >>= (return . f)
join n = n >>= id
m >>= g ≡ join (fmap g m)
Here, m has the type Monad m => m a, n has the type Monad m => m (m a), f has the type a -> b, and g has the type Monad m => a -> m b, where a and b are underlying types.
The fmap function is defined for any functor in the category of types and functions, not just for monads. It is expected to satisfy the functor laws:
fmap id ≡ id
fmap (f . g) ≡ (fmap f) . (fmap g)
The return function characterizes pointed functors in the same category, by accounting for the ability to “lift” values into the functor. It should satisfy the following law:
return . f ≡ fmap f . return
In addition, the join function characterizes monads:
join . fmap join ≡ join . join
join . fmap return ≡ join . return = id
join . fmap (fmap f) ≡ fmap f . join
Hope that helps.
As a few people have commented, you've found a really cute property about monads here. For reference, let's look at the signature for bind:
:: Monad m => m a -> (a -> m b) -> m b
In your case, the type a === m b as you have a [[a]] or m (m a). So, if you rewrite the signature of the above bind operation, you get:
:: Monad m => m (m b) -> ((m b) -> m b) -> m b
I mentioned that this is cute, because by extension, this works for any nested monad. e.g.
:: [[b]] -> ([b] -> [b]) -> [b]
:: Maybe (Maybe b) -> (Maybe b -> Maybe b) -> Maybe b
:: Reader (Reader b) -> (Reader b -> Reader b) -> Reader b
If you look at the function that get's applied here, you'll see that it's the identity function (e.g. id, same, :: forall a. a -> a).
This is included in the standard libraries for Haskell, as join. You can look at the source here on hackage. You'll see it's implemented as bind id, or \mma -> mma >>= id, or (=<<) id
As you say m is []. Then a is [Integer] (ignoring the fact that numbers are polymorphic for simplicity's sake) and b is Integer. So a -> m b becomes [Integer] -> [Integer].
First: we should use the standard version of same, it is called id.
Now, let's rename some type variables
id :: (a'' ~ a) => a -> a''
What this means is: the signature of id is that of a function mapping between two types, with the extra constraint that both types be equal. That's all – we do not require any particular properties, like “being flat”.
Why the hell would I write it this way? Well, if we also rename some of the variables in the bind signature...
(>>=) :: (Monad m, a'~m a, a''~m b) => a' -> (a -> a'') -> a''
...then it is obvious how we can plug the id, as the type variables have already been named accordingly. The type-equality constraint a''~a from id is simply taken to the compound's signature, i.e.
(>>=id) :: (Monad m, a'~m a, a''~m b, a''~a) => a' -> a''
or, simplifying that,
(>>=id) :: (Monad m, a'~m a, m b~a) => a' -> m b
(>>=id) :: (Monad m, a'~m (m b)) => a' -> m b
(>>=id) :: (Monad m) => m (m b) -> m b
So what this does is, it flattens a nested monad to a single application of that same monad. Quite simple, and as a matter of fact this is one the “more fundamental” operation: mathematicians don't define the bind operator, they instead define two morphisms η :: a -> m a (we know that, it's return) and μ :: m (m a) -> m a – yup, that's the one you've just discovered. In Haskell, it's called join.
The monad here is [a] and the example is pointlessly complicated. This’ll be clearer:
Prelude> [[1]] >>= id
[1]
just as
Prelude> [[1]] >>= const [2]
[2]
i.e. >>= is concatMap and is concat when used with id.

Function passed to list monad bind can be the identity without a compiler error

When applying the list monad bind function to a simple list and identity function:
[[1,2],[3,4]] >>= \x -> x
I get
[1,2,3,4]
However, the definition of the Monad type class:
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
seems to suggest that the function, in my case the lambda function \x -> x, should return a different type to the one passed in. I would expect a compiler error in this case, but I don't have one. I'm running this in ghci.
Why doesn't the compiler throw an error in this case?
The identity function id :: a -> a, or explicitly \x -> x is polymorphic. This means it can be specialized to any type which you construct by substituting some type for a.
In your case (>>= id) the compiler looks at the type of the second argument of
(>>=) :: m c -> (c -> m d) -> m d
and at the type of id and tries to unify them:
a -> a -- id
c -> m d -- the second argument of >>=
this is satisfied in the most general way when we substitute a = m d and c = m d. So the most general type of id inside the expression(>>= id) is
id :: m d -> m d
and the type of the whole expression is
(>>= id) :: (Monad m) => m (m d) -> m d
which is the join function.
a, m and b are type variables and there is nothing that prevents a from being equal to m b in a given situation. That's the idea of polymorphism: if something has type a without any more constraints on a, then it also has type Int, and [[Bool]], and c -> [Int] -> d, and (like here) m b.
So for this specific call, a ~ [Int], b ~ Int, m ~ [], and therefore (>>=)'s type is [[Int]] -> ([Int] -> [Int]) -> [Int].
The inner list is seen as the outer list in the output, but a list is a list nevertheless.
The other way to say this is that
foreach x in [[1,2],[3,4]]:
foreach y in x:
emit y
and
foreach x in [1,2,3,4]:
emit x
are "the same" as regards the emitted elements.
I find the type presentations with lined-up subentities much visually appealing:
(>>=) :: m a -> (a -> m b) -> m b
[[1,2],[3,4]] :: [[Int]] -- actually, (Num a) => [[a]], but never mind that
\x -> x :: a -> a
(>>=) :: m a -> ( a -> m b) -> m b
(>>=) [[1,2],[3,4]] :: ( a -> m b) -> m b m a ~ [[Int]]
(>>=) [[1,2],[3,4]] :: ( a -> [b]) -> [b] m ~ []
(>>=) [[1,2],[3,4]] :: ([Int] -> [b]) -> [b] a ~ [Int]
(>>=) [[1,2],[3,4]] (\ x -> x ) :: [b] [b] ~ [Int]
(>>=) [[1,2],[3,4]] (\ x -> x ) :: [Int] b ~ Int
-- actually, (Num b) => b
Here, it turns out, \ x -> x :: (Num b) => [b] -> [b], not just a -> a.
You see, when ([Int] -> [b]) is matched with the type of (\ x -> x), creating the equivalence of [Int] ~ [b], the [] in [Int] comes from the "inner list", the a in m a; and the [] in [b] comes from the "outer list", the m in m b; but a list is a list, as was said above.
And that's what allows the two list levels to be smashed ("joined") into one — "flattening" a list, or more generally "joining" the two "levels" of a monad into one.
Another way to see it is to expand the monadic code with its specific list version:
[[1,2],[3,4]] >>= \x -> x
=== concatMap id [[1,2],[3,4]] === concat [ x | x <- [[1,2],[3,4]]]
=== concat [id [1,2], id [3,4]] === [ y | x <- [[1,2],[3,4]], y <- x]
=== [1,2,3,4] === [1,2,3,4]
All that matters for f in concatMap f is for it to be a list-producing function: f :: a -> [b].
And concatMap id === concat :: [[a]] -> [a] is a perfectly legal function. Yes, concat is join for the list monad:
ma >>= f === join (fmap f ma) -- or, for lists,
=== concat (map f ma)
=== concatMap f ma -- the definition that we used above

Haskell: Rigid type variable error when pattern matching bind operator

I'm trying to run this
newtype Test a = Test (Int, a)
instance Monad Test where
Test (_, []) >>= k =
k []
Test (_, a) >>= k =
k a
return a =
Test (0, a)
And I get the error:
Couldn't match expected type `a' with actual type `[t0]'
`a' is a rigid type variable bound by
the type signature for >>= :: Test a -> (a -> Test b) -> Test b
at C:\Users\david.phillips\Documents\code\test.hs:4:5
In the pattern: []
In the pattern: (_, [])
In the pattern: Test (_, [])
I get a similar error when I tried using a case statement instead of 2 versions of >>=.
I'm fairly new to haskell and can't see why this wouldn't work.
Edit: Sorry, it's a bad example. Suppose that the first definition of >>= gave a different output.
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
Monad instances are parameterized over a type variable a. You are essentially claiming that it is not, because in the place of that variable, you have pattern matched on the empty list constructor, [], meaning "a is a list of something." The type of eg. bind could, with explicit quantification, be written:
(>>=) :: forall a. m a -> (a -> m b) -> m b
Your definition cannot possibly hold for ALL a.
As an addition to Sarah's answer, you can actually omit your specific pattern match,
Test (_, []) >>= f = f []
is the same as
Test (_, a) >>= f = f a
So you can really just write this as
Test (_, a) >>= f = f a
return a = (0, a)
Now remember that in addition to have the right types, we're supposed to have that
m >>= return = m
return a >>= f = f a
(a >>= b) >>= c = a >>= (\a' -> b a' >>= c)
This worries me though, as
m = Test (1, 'c')
m >>= return === return 'c' === (0, 'c') /== m
So return is no longer functioning as an identity and you're breaking the 1st monad law. Fixing this would mean return would have to preserve the first element of the tuple, problematic since we don't actually tell it about it.
Naively, let's just clobber the first tuple element that our function returns.
Test (a, b) >>= f = Test (a, snd (f b))
Now
Test (1, 'c') >>= return == Test (1, snd (return 'c')) == Test (1, 'c')
But we're still in trouble,
let f a = Test (1, a)
return a >>= f == Test (0, snd (f a)) == Test (0, a) /== f a
So the trick here is to do what the state monad does
newtype Test a = Test{ unTest :: Int -> (Int, a) }
instance Monad Test where
return a = Test $ \i -> (i, a)
(Test m) >>= f = Test $ \i -> let (i', a) = m i
in unTest (f a) $ i'
Which does satisfy the monad laws*. Happily this already exists in Control.Monad.State.
** modulo seq
Get rid of the first pattern. You are trying to make a separate definition for a specific type, which you can't do. All of the definitions need to be for all types a. If you could violate that, the first pattern would be the same as the second pattern but with a bound to [], so just write:
instance Monad Test where
Test (_, a) >>= k =
k a
return a =
Test (0, a)
Test (0, []) >>= k would then match the >>= pattern, and become k [], exactly the same as what your first pattern is unnecessarily trying to do.

Resources