Haskell Applicative [] why can I not replace pure[] with [] in function? - haskell

ghci> :t pure []
pure [] :: Applicative f => f [a]
ghci> pure []
[]
ghci> :t []
[] :: [a]
ghci> fmap ((:) 2) (pure [])
[2]
ghci> fmap ((:) 2) ([])
[]
I would have thought replacing pure[] with [] in fmap ((:) 2) (pure []) would result in the same outcome.. who can explain the difference to me?

The type of pure is Applicative f => a -> f a so pure []
has type Applicative f => f [a]. You can specify f explicitly for different applicative types e.g.
pure [] :: Maybe [String] //Just []
pure [] :: IO [String] //displays '[]' in ghci
pure [] :: [[String]] //[[]]
The type of fmap ((:) 2) (pure []) is (Applicative f, Num a) => f [a]. Since Ghci runs in the IO monad, which is an Applicative, it chooses f to be IO, and displays the resulting list [2] which is what you see.
You can specify the applicative type directly to see a different result e.g.
fmap ((:) 2) (pure []) :: (Maybe [Int])
which is Just [2]
In fmap ((:) 2) ([]), there are no elements in the input list so you get an empty list.

Why would it be the same? They're different expressions.
Perhaps it simplifies things if we just look at lists. So, there's the empty list []. Its type can be anything with brackets around it, in particular also a nested list:
Prelude> [] :: [[Int]]
[]
But there's also another "empty nested list":
Prelude> [[]] :: [[Int]]
[[]]
This one isn't really empty though, it merely contains only the empty list. ([[],[],[],...] would also be possible). In fact, that would be the result of what you've tried, if done in the list applicative:
Prelude Control.Applicative> pure [] :: [[Int]]
[[]]
It is certainly not the same as the empty list,
Prelude> [[]] == []
False
In particular,
Prelude> (length [], length [[]])
(0,1)
And fmappming over an empty list never does anything, while fmapping over an empty-containing list will call the function with []: an easy way to see this is
Prelude Control.Applicative> fmap undefined []
[]
Prelude Control.Applicative> fmap undefined [[]]
[* Exception: Prelude.undefined
The real confusing thing about your trials is that ghci silently uses the IO monad.
There's also a subclass of Applicative for actual emptiness:
Prelude Control.Applicative> :i Alternative
class Applicative f => Alternative f where
  empty :: f a
  (<‌|>) :: f a -> f a -> f a
  some :: f a -> f [a]
  many :: f a -> f [a]
  -- Defined in `Control.Applicative'
instance Alternative [] -- Defined in `Control.Applicative'
instance Alternative Maybe -- Defined in `Control.Applicative'

Related

Convert Tuple into Foldable

Is there a way to derive Foldable from Tuple?
At least when the tuple is homogeneous?
For example let's say I have (1,2,3) and I want to reverse it or to transform it into [1,2,3] and similar things.
I've tried to do something like
over each (\x -> 4 -x) (1,2,3) -- lol
but I need a sort of equivalent of fold with lens...
and actually I see that I can do
foldr1Of each (\a x -> a+x) (1,2,3)
but I would need instead
foldr1Of each (\a x -> a:x) (1,2,3)
which doesn't compile
but I would need instead
foldr1Of each (\a x -> a:x) (1,2,3)
which doesn't compile
The reason why this does not compile is because (:) :: a -> [a] -> [a] expects a list as second argument, but with foldr1Of, you provide it the last element of your fold, which is here a number.
You can solve it by using foldrOf :: Getting (Endo r) s a -> (a -> r -> r) -> r -> s -> r instead:
Prelude Control.Lens> foldrOf each (:) [] (1,2,3)
[1,2,3]
Here we thus pass [] as the "initial accumulator".
We can thus convert several several "containers" to lists with:
toList :: Each s s a a => s -> [a]
toList = foldrOf each (:) []
For example:
Prelude Control.Lens> toList (1,2)
[1,2]
Prelude Control.Lens> toList (1,2,3)
[1,2,3]
Prelude Control.Lens> toList (1,2,3,4)
[1,2,3,4]
Prelude Control.Lens> toList [1,2,3]
[1,2,3]
Prelude Control.Lens> toList Nothing
[]
Prelude Control.Lens> toList (Just 2)
[2]
In addition to Willem's answer, it is worth noting that Control.Lens.Fold offers analogues for pretty much everything in Data.Foldable. That includes toList, which becomes toListOf:
GHCi> toListOf each (1,2,3)
[1,2,3]

How to concatenate a value to a list when both are inside Maybes?

I'm reading realworldhaskell and I've come to chapter 4 where the book talks about "Safely and sanely working with crashy functions". I'm trying to write a safe version of init :: [a] -> [a]. This is as far as I got:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) = ???
I get that I can't do something like x : mySafeInit xs, because that would be like doing a : Just [a] (right?). I've read about fmap though, so I tried this:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) = fmap (:) (Just x) (mySafeInit xs)
Well that's guaranteed to work, right? Well no, and I'm struggling to understand why. Here I have a Just a and a Just [a], right? Shouldn't I be able to use fmap, give it the function (:) and my two maybes, and get a Just [a] back?
After some googling I did figure out that this works:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) = fmap (:) (Just x) <*> (mySafeInit xs)
but I don't understand why. Could someone walk me through this? :)
Let's look at
fmap (:) (Just x) (mySafeInit xs)
For Maybe, fmap is defined as
fmap _ Nothing = Nothing
fmap f (Just x) = Just (f x)
Therefore
fmap (:) (Just x)
is
Just ((:) x)
Note that this is not a function; it's a Maybe value of some type (in fact, it's Maybe ([a] -> [a])). That's why
(Just ((:) x)) (mySafeInit xs)
is a type error (you can only apply functions).
In the second version of your code, you did
fmap (:) (Just x) <*> (mySafeInit xs)
, which is
(Just ((:) x)) <*> (mySafeInit xs)
Looking at the type of <*>, we get:
(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b
Here f is Maybe, and a and b are both [a]:
(<*>) :: Maybe ([a] -> [a]) -> Maybe [a] -> Maybe [a]
That's why this version checks out.
Shouldn't I be able to use fmap, give it the function (:) and my two maybes, and get a Just [a] back?
No, because fmap only works with functions of one argument. There is another function for two arguments, though:
liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
Contrast with
fmap :: (Functor f) => (a -> b) -> f a -> f b
liftA2 (:) (Just x) (mySafeInit xs) should indeed work.
But it's needlessly complicated because one of your maybes is artificial: You explicitly wrapped your x in Just. You can simply do this instead:
fmap ((:) x) (mySafeInit xs)
By the definition of fmap, this is either Nothing (if mySafeInit xs is Nothing) or Just ((:) x y) (if mySafeInit xs is Just y).
Simple solution
I think you make things too hard/complex. You can simply consider two cases:
the empty list, in which case you return a Nothing; and
the non-empty list, in which case you can use the old init:
Or putting it into code:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit l = Just (init l)
Now of course we have to trust that there are only two constructors for a list; and that init will only error when we provide it an empty list. Both assumptions hold, but can (although very unlikely) change in the future.
We can however use our own init function:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (l:ls) = Just (init l ls)
where init _ [] = []
init x (x2:xs) = x : init x2 xs
Now the Haskell compiler can verify that both functions are syntactically total. Note that functions can be total, but not syntactically: for instance because we can make assumptions regarding the structure of the data that the compiler can not check.
Working with fmap
You provide a solution like:
-- ...
mySafeInit (x:xs) = fmap (:) (Just x) <*> (mySafeInit xs)
A first aspect we have to understand is that Maybe is a Functor. A Fuctor supports a function fmap where we map the item(s) inside the functor so to speak. For instance a list is a functor as well, and we can thus map all elements in the list with fmap f somelist. You can see Maybe as some sort of list with zero elements (the Nothing) or one element (the Just x). So in case we perform fmap on a Nothing, we get a Nothing back, in case we perform this on a Just x, we get Just (f x).
Here we see fmap (:) (Just x). Since we thus apply it on a Just x, we have actually constructed:
fmap (:) Just x
-> Just ((x :))
This is thus a Just, but it carries a function (x : ), not a value.
Next we see a <*> operator. (<*>) :: Applicative f => f (a -> b) -> f a -> f b is some sort of "multiplication" over an Applicative (a Maybe is an applicative as well). On the left side we have an applicative of functions a -> b, on the right side an applicative of as. The result is an applicative of bs: for every tuple of functions and values.
In case we perform this on a list, we thus obtain a list that starts with the values all applied to the first function, then all values applied to the second function, etc.
For a Maybe we thus have a Maybe (a -> b) left and a Maybe a on the right. In case these are of the form Just f and Just x, we obtain Just (f x), in all other cases we obtain Nothing.
Since we perform a recursive call on mySafeInit xs, we thus obtain the init of the remaining list wrapped in a Just. In that case, we thus prepend that result with xs.
An equivalent code definition is thus:
mySafeInit :: [a] -> Maybe [a]
mySafeInit [] = Nothing
mySafeInit (_:[]) = Just []
mySafeInit (x:xs) | Just ys <- mySafeInit xs = Just (x:ys)
| otherwise = Nothing

Redefining monad list instance

I am attempting to redefine the monad list instance using newtype to create a wrapped list type, so as to allow this to be done at all, since it seems the Prelude definitions are unable to be overridden.
So far I have the following:
newtype MyList a = MyList { unMyList :: [a] }
deriving Show
myReturn :: a -> [a]
myReturn x = [x]
myBind :: [a] -> (a -> [b]) -> [b]
myBind m f = concat $ map f m
instance Monad MyList where
return x = MyList [x]
xs >>= f = undefined
As a beginner in Haskell, I am at a loss to know how to define the >>= operator for the instance, using my function for the definition of bind.
Should the myReturn and myBind functions have types using MyList rather than plain type variables? How does one do the packing and unpacking necessary to define >>= properly?
I am getting stuck on the function argument to map f, where f :: a -> [b], but it seems I need f :: a -> MyList b, but then map won't accept that as an argument.
Apologies for the confusion. All assistance appreciated.
[I am aware there is a similar question here: Redefine list monad instance but I'm afraid I cannot follow the answers there.]
You simply need to unwrap your MyList type, operate on it, then wrap it back up:
instance Monad MyList where
return x = MyList [x]
(MyList xs) >>= f = MyList . concat . map unMyList . map f $ xs
You can (and should) condense this to MyList $ concatMap (unMyList . f) xs, but I've left it expanded for illustrative purposes. You could simplify this definition by defining your own map and concat functions for MyList:
myMap :: (a -> b) -> MyList a -> MyList b
myMap f (MyList xs) = MyList $ map f xs
myConcat :: MyList (MyList a) -> MyList a
myConcat (MyList xs) = MyList $ concat $ map unMyList xs
myConcatMap :: (a -> MyList b) -> MyList a -> MyList b
myConcatMap f xs = myConcat $ myMap f xs
instance Monad MyList where
return x = MyList [x]
xs >>= f = myConcatMap f xs
And now it looks like the normal list instance:
instance Monad [] where
return x = [x]
xs >>= f = concatMap f xs

Mapping `apply` to List of Functions

Learn You a Haskell demonstrates mapping with currying:
*Main> let xs = map (*) [1..3]
xs now equals [(1*), (2*), (3*)]
EDITED to correct order per Antal S-Z's comment.
We can get the first item in the list, and apply 3 to it - returning 3*1.
*Main> (xs !! 0) 3
3
But, how can I apply the below foo to apply 1 to all curried functions in xs?
*Main> let foo = 1
*Main> map foo xs
<interactive>:160:5:
Couldn't match expected type `(Integer -> Integer) -> b0'
with actual type `Integer'
In the first argument of `map', namely `foo'
In the expression: map foo xs
In an equation for `it': it = map foo xs
Desired output:
[1, 2, 3]
Use the ($) function...
Prelude> :t ($)
($) :: (a -> b) -> a -> b
...passing just the second argument to it.
Prelude> let foo = 2
Prelude> map ($ foo) [(1*), (2*), (3*)]
[2,4,6]
Have you tried using applicative functors?
import Control.Applicative
main = (*) <$> [1,2,3] <*> pure 1
The <$> function is the same as fmap in infix form. It has the type signature:
(<$>) :: Functor f => (a -> b) -> f a -> f b
The <*> function is the functor equivalent of $ (function application):
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
The pure function is similar to return for monads. It takes a normal value and returns an applicative functor:
pure :: Applicative f => a -> f a
Hence the expression (*) <$> [1,2,3] <*> pure 1 is similar to applying the (*) function to all the values of [1,2,3] and pure 1. Since pure 1 only has one value it is equivalent to multiplying every item of the list with 1 to produce a new list of products.
Or you could use anonymous function:
map (\x -> x foo) xs

List monad: difference between `>>=` and `return` behaviors

I'm just getting started on monads, and I can't figure out why these two expressions evaluate differently:
ghci> [1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch)
[(1,'a'),(1,'b'),(2,'a'),(2,'b')]
ghci> return ([1,2],['a','b'])
([1,2],"ab")
The types are different, so it's reasonable that the behaviors are different
The first expression would typecheck as Num t => [(t, Char)]
The use of [] as the monad in the (>>=) means that it infers that the monad should be the List monad and in the context of the List Monad http://en.wikibooks.org/wiki/Haskell/Understanding_monads/List (>>=) is concatMap and return is (:[]).
[1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch)
is the same as
concatMap (\n -> concatMap (\ch -> [(n, ch)]) ['a', 'b']) [1,2]
which returns [(1,'a'),(1,'b'),(2,'a'),(2,'b')]
In your second example what's really going on is
that the type of the expression is a bit more general:
Prelude> :t return ([1,2],['a','b'])
return ([1,2],['a','b']) :: (Monad m, Num t) => m ([t], [Char])
Because you're running it in GHCi a few things happen. GHCi can be considered a very big special IO Monad. So since no monad was specified, when GHC tries to print the results, it'll take the m Monad to be IO in this case.
The t is defaulted to Integer as well, so the type of the resulting expression is :: IO ([Integer], [Char]).
As it happens, all the types used have a Show instance, so GHC can print the results of executing the IO action, which in this case (due to the action being return) is the same as the input.
In GHCi, you can interactively check the type of an expression using :t. Doing so shows that your expressions have different types:
ghci> :t [1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch)
[1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch)
:: (Num t) => [(t, Char)]
ghci> :t return ([1,2],['a','b'])
return ([1,2],['a','b']) :: (Num t, Monad m) => m ([t], [Char])
Thus, they have different values.
Perhaps you're confused by the presence of monads inside the argument to return. However, look at its type:
ghci> :t return
return :: Monad m => a -> m a
return knows nothing about its argument -- it just takes a value, any value, and places it in a default, monadic context.
To understand exactly what happens when these expressions are evaluated, you'll need:
Hoogle, to find the monad instance for lists, and
a more specific type for the second expression
Here's the monad instance:
instance Monad [] where
m >>= k = foldr ((++) . k) [] m
m >> k = foldr ((++) . (\ _ -> k)) [] m
return x = [x]
fail _ = []
(We can ignore >> and fail, since we're not using them.)
So let's expand our expression:
[1,2] >>= \n -> ['a','b'] >>= \ch -> return (n,ch)
so setting m = [1, 2] and k = \n -> ['a','b'] >>= \ch -> return (n,ch) we get:
foldr ((++) . (\n -> ['a','b'] >>= \ch -> return (n,ch))) [] [1,2]
now to get rid of the second >>=, m = ['a', 'b'] and k = \ch -> return (n, ch):
foldr ((++) . (\n -> rest)) [] [1,2]
where
rest = foldr ((++) . (\ch -> return (n,ch))) [] ['a', 'b']
and return is easy to get rid of:
foldr ((++) . (\n -> rest)) [] [1,2]
where
rest = foldr ((++) . (\ch -> [(n,ch)]) [] ['a', 'b']
On the other hand, the value of the 2nd expression:
return ([1,2],['a','b'])
depends on which monad you're in. In the list monad, it simply becomes:
[([1,2], ['a','b'])] :: [] ([Int], String)
whereas in the Maybe monad, it's:
Just ([1,2], ['a', 'b']) :: Maybe ([Int], String)

Resources