Understanding `mapA` to Gain Intuition - haskell

I'm working on an exercise from Brent Yorgey's 2013 UPenn lecture to implement mapA.
mapA :: Applicative f => (a -> f b) -> ([a] -> f [b])
I'm trying to gain intuition for this function. How is this function useful? I'm not questioning its utility - just trying to understand it.
Additionally, I'm looking for a hint to go from a -> f b to [a] -> f [b].

If we knew nothing at all about f then a function like a -> f b would let us put things into f-boxes but then we'd be completely stuck. You're probably familiar with Functor. If we know f were a Functor then we'd be able to transform the thing inside of f, but we're still basically stuck---f forms an unmoving wall we cannot cross.
Why do we care? Well, when we try to construct the function [a] -> f [b] we need to some how operate on a collection of as. We could, perhaps, just pull the first one off if we liked (and it existed) and feed it through a -> f b then wrap the result in a list:
unsatisfying :: Functor f => (a -> f b) -> ([a] -> f [b])
unsatisfying inject (a : _) = fmap (\x -> [x]) (inject a)
but not only do we have an incomplete pattern match on [a], we're clearly violating something in the spirit of this function---we'd much prefer to use all of the as. Unfortunately, knowing only f or even that f is a Functor gets us only as far as
stillUnsatisfying :: Functor f => (a -> f b) -> ([a] -> [f b])
stillUnsatisfying inject as = map inject as
The problem is that just because we have a collection of f-containers doesn't mean we can find any way to treat them collectively. We'd like to somehow "glue" our collection [f b] all together. If we could do that then a function like [a] -> f [b] would sound like "explode our list [a] into pieces, pass them each individually into f using inject, glom all of the (f b)s together, and then reassemble the list on the inside".
Clearly we need a way to "glom" Functors together and also a way to operate on the separate pieces "on the inside" of f.
So this is where Applicative comes in. I'm not going to introduce it exactly, though. Instead, let's look at an equivalent type class
class Functor f => Monoidal f where
basic :: a -> f a
glom :: f a -> f b -> f (a, b)
It's an interesting exercise to prove that Monoidal and Applicative are equivalent, but immediately you can see that glom provides exactly what we're looking for. Moreover, basic/pure give us the ability to inject raw pieces of our list into f as we need them (for instance, if our [a] is empty then we'll need to inject an empty list into f without using a -> f b as we cannot---that looks like basic [] :: f [b]).
So Applicative provides you the ability to not only transform inside of functors but also to glom a bunch of functors together and operate on all of their pieces inside of the functor.

You're halfway there, but the final function you're looking for is the sequenceA function that's defined in LYAH. Here's my implementation:
sequenceA :: Applicative f => [f a] -> f [a]
sequenceA = foldr ((<*>) . fmap (:)) (pure [])
From there the mapA function is easy as pie. Just add another argument and compose the two functions:
mapA :: Applicative f => (a -> f b) -> [a] -> f [b]
mapA f xs = foldr ((<*>) . fmap (:) . f) (pure []) xs
-- Or, you could implement it this more elegant, albeit slightly slower, way:
mapA = (sequenceA .) . map
And there you have an implementation for you to have a look at. As for the usefulness, it's particularly useful in IO, when you have a list like ["Foo","Bar","Baz"], and you'd like to putStrLn all of those functions. Do do so, you will need to map each value and the sequence it, which mapA does. Note that these functions have monadic equivalents, but it's a good exercise to implement them in purely Applicative ways.
These functions are both quite useful when dealing with lists of Applicatives, allowing one to more easily manipulate the values inside them without using half a ton of fmaps.

We already know that map :: (a -> b) -> ([a] -> [b]) is useful. It applies a function to every element of a list.
A loose but enlightening interpretation of a -> f b for an applicative f is that it is a function which takes an a, performs an applicative "action", and returns a b. For example if f is IO then the "action" might be reading from a disk. mapA :: (a -> f b) -> ([a] -> f [b]) can be interpreted as applying this "function" to every element of the list.

Related

Cartesian product set generation [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 months ago.
Improve this question
I am trying to create a Haskell function to generate a Cartesian product of two lists
Here's my attempt:
cartesianProduct :: (a -> b -> c) -> [a] -> [b] -> [c]
cartesianProduct f x [] = x
cartesianProduct f y [] = y
cartesianProduct = f x y unionHelper func1 f xs ys
If you're in a hurry, then the function is called liftA2 and it's actually built-in.
sort $ liftA2 (*) [1,2,4] [1,3,9] -- [1,2,3,4,6,9,12,18,36]
But, of course, that's not very enlightening, so let's talk about how we might do it ourselves.
The list type, [], is a functor. We can implement fmap directly using recursion.
fmap :: (a -> b) -> [a] -> [b]
fmap _ [] = []
fmap f (x:xs) = f x : fmap f xs
Now we have a way of to do something for each element of a list. Great, that's how we'll apply our final operation, but we need to generate all of the argument lists as well. Specifically, we want to produce the Cartesian product.
cross :: [a] -> [b] -> [(a, b)]
And we can do so recursively as well, using our fmap function to help out.
cross :: [a] -> [b] -> [(a, b)]
cross [] _ = []
cross (x:xs) ys = fmap ((,) x) ys ++ cross xs ys
Recursion on the first element. If the first argument is empty, then the Cartesian product is empty. If the first argument is nonempty, then the result should consist of the head paired with each (via fmap) element of the second argument, followed by the Cartesian product of the tail with the second list.
Now we have a way to get a [(Int, Int)]. And we want to multiply those elements, so it's just a matter of tying it all together.
apply2 :: (a -> b -> c) -> [a] -> [b] -> [c]
apply2 f xs ys = fmap (\(x, y) -> f x y) $ cross xs ys
Take the Cartesian product of the two lists, then apply our function f (uncurried) to each element.
This gives us our result, in a slightly different order than in your example. But it looks like you're sorting the results anyway, rather than producing them in an algorithmic order.
sort $ apply2 (*) [1,2,4] [1,3,9] -- [1,2,3,4,6,9,12,18,36]
Now, let's talk about why liftA2 works. The list type is an example of an applicative functor, represented by the Applicative typeclass. Whereas fmap (which is part of Functor) takes a single function and maps it over a functor (in our case, over several elements of a list), the fundamental applicative operation is <*> (pronounced "ap"), whose signature is
fmap :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Instead of mapping a single simple function over a functor value f a, we're mapping a function inside the functor f (a -> b) over a value also inside the functor f a. Now, this is a jumble of words, but in the case of lists it looks like
fmap :: (a -> b) -> [a] -> [b]
(<*>) :: [a -> b] -> [a] -> [b]
Rather than applying a single function to several elements, we're applying several functions to several elements. (<*>) is actually just our cross function written in a slightly different way. It's combining two lists using every combination to produce a result of some type. (In fact, the relationship between our cross and the applicative (<*>) is rather deep mathematically, due to the fact that (->) and (,) are adjoint to each other, but that's getting off track)
So (<*>) is just cross by another name. And liftA2 is defined as (something equivalent to)
liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
liftA2 f a b = fmap f a <*> b
It's just doing fmap and (<*>), which is basically what our apply2 function was doing to begin with. Again, it's slightly shuffled around since we're using (->) rather than (,) (since our "ap" operator applies a function rather than building a tuple), but it's exactly the same idea.
Certainly, the liftA2 approach is snazzy and short, but don't let it blind you. There's nothing wrong with a recursive approach, especially as you're learning. If apply2 makes more sense to you and my explanation above of the applicative functors was nonsense, then go for it. You can go a long way in Haskell learning about recursion and data structures before really grokking functors, and that's fine. But when you're ready, I recommend Typeclassopedia for an excellent summary of the Haskell typeclasses that represent functors, applicative functors, monads, and all of the other lesser-known abstractions available to the programmer.
Good luck, and happy coding!

I need a monad solution to a functor simplification

This extends from a solution I have used for my this question
data CoroMap a = CoroMap (ColorMap (RoleMap a))
instance Functor CoroMap where
fmap fn (CoroMap coro) =
CoroMap $ fmap (fmap fn) coro
visions:: Piese -> [Vision]
visions p = []
ihavethis :: CoroMap [Piese]
ineedthis:: CoroMap [Vision]
-- ineedthis = ???
-- I have this a -> [b]
-- I need this [a] -> [b]
-- specifically converting CoroMap [Piese] to CoroMap [Vision]
-- using Piese -> [Vision]
I have this a -> [b]
I need this [a] -> [b]
A lot of questions like this in Haskell basically boil down to "following the types" - meaning that (sometimes, although not always) you don't have to think too hard about what you actually want the function to do, you just need the types to match up. (This might seem rather miraculous, and in a way it is - it's due to the fact that types in Haskell give you so much information compared to many other statically-typed languages.) And the ability to pick a function which has the right type often simply comes with a bit of experience.
Even if you don't have much experience, there is a very good way to "cheat" - go to Hoogle and type in the type signature you are interested in. Here, entering
(a -> [b]) -> [a] -> [b]
and letting it search will bring up a lot of relevant results, of which the very first is concatMap. This is the function that, given such a function of type a -> [b] and a list of type [a], first maps the function over the list, resulting in a list of lists ([[b]]), then concatenates those together to get a simple [b]. That's very likely what you want (and seems to be the case, based on your response to my comment suggesting it).
In terms of being able to spot this without needing a helper like Hoogle - Monads are ubiquitous in Haskell, and lists are one of many very common type which form a monad. Seeing therefore that you have a a -> m b (for a particular monad m) and want a m a -> m b, any Haskeller with a little bit of experience will instantly think of the fundamental method of the Monad typeclass, which is (>>=) (pronounced "bind"), and has type
(Monad m) => m a -> (a -> m b) -> m b
This is very close to what you want, the only difference is that you have to flip it, to get:
flip (>>=) :: (Monad m) => (a -> m b) -> m a -> m b
which due to currying (aka "arrows in type signatures are right-associative"), is the same as
flip (>>=) :: (Monad m) => (a -> m b) -> (m a -> m b)
which is exactly what you asked for, only it will work for all Monads, not just lists. That's how I came up with concatMap, because (>>=) for lists is defined to be flip concatMap, so the flip (>>=) that you want is simply concatMap.
Note also that the Hoogle search I mentioned above lists (=<<) a short way down - that's just an abbreviation for flip (>>=). So this all marries up nicely.
Finally, for your bonus question:
I need this function f [a] -> (a -> [b]) -> f [b]
where from context f is a Functor - this is just a case of combining what we already have:
concatMap :: (a -> [b]) -> ([a] -> [b])`
with fmap. Given g :: a -> [b] we know concatMap g is of type [a] -> [b], so fmap (concatMap g) is of type f [a] -> f [b]. In other words, \g -> fmap (concatMap g) (which you can also write as fmap . concatMap) has type (a -> [b]) -> f [a] -> f [b], so we simply need to apply swap the arguments. So the function you want is
flip (fmap . concatMap)
in pointfree form, or if you prefer explicit arguments (which looks less elegant but is often easier to understand), you can write it as
\as g -> fmap (concatMap g) as

Any function with the same polymorphic type as fmap must be equal to fmap?

I'm reading the second edition of Programming in Haskell and I've came across this sentence:
... there is only one way to make any given parameterised type into a functor, and hence any function with the same polymorphic type as fmap must be equal to fmap.
This doesn't seem right to me, though. I can see that there is only one valid definition of fmap for each Functor type, but surely I could define any number of functions with the type (a -> b) -> f a -> f b which aren't equivalent to each other?
Why is this the case? Or, is it just a mistake by the author?
You've misread what the author was saying.
...any function with the same polymorphic type as fmap...
This means, any function with the signature
Functor f => (a -> b) -> f a -> f b
must be equivalant to fmap. (Unless you permit bottom values, of course.)
That statement is true; it can be seen quite easily if you try to define such a function: because you know nothing about f except that it's a functor, the only way to obtain a non-⊥ f b value is by fmapping over the f a one.
What's a bit less clear cut is the logical implication in the quote:
there is only one way to make any given parameterised type into a functor, and hence any function with the same polymorphic type as fmap must be equal to fmap.
I think what the author means there is, because a Functor f => (a -> b) -> f a -> f b function must necessarily invoke fmap, and because fmap is always the only valid functor-mapping for a parameterised type, any Functor f => (a -> b) -> f a -> f b will indeed also in practice obey the functor laws, i.e. it will be the fmap.
I agree that the “hence” is a bit badly phrased, but in principle the quote is correct.
I think that the quote refers to this scenario. Assume we define a parameterized type:
data F a = .... -- whatever
for which we can write not only one, but two fmap implementations
fmap1 :: (a -> b) -> F a -> F b
fmap2 :: (a -> b) -> F a -> F b
satisfying the functor laws
fmap1 id = id
fmap1 (f . g) = fmap1 f . fmap1 g
fmap2 id = id
fmap2 (f . g) = fmap2 f . fmap2 g
Under these assumptions, we have that fmap1 = fmap2.
This is a theoretical consequence of the "free theorem" associated to fmap's polymorphic type (see the comment under Lemma 1).
Pragmatically, this ensures that the instance we obtain from deriving Functor is the only possible one.
It is a mistake. Here's some examples of functions with the same type as fmap for lists that are not fmap:
\f -> const []
\f -> concatMap (replicate 2 . f)
\f -> map (f . head) . chunksOf 2
\f -> map f . reverse
There are many more. In general, given a function ixf from list lengths to lists of numbers no bigger than that length (that is, valid indices into the list), we can build
maybeIt'sFmapLol :: (Int -> [Int]) -> (a -> b) -> [a] -> [b]
maybeIt'sFmapLol ixf elemf xs = [map elemf xs !! ix | ix <- ixf (length xs)]
Use suitably lazy variants of Int to handle infinite lists. A similar function schema can be cooked up for other container-like functors.

Understanding signature of function traverse in haskell

traverse :: Applicative f => (a -> f b) -> t a -> f (t b)
Hi,
There are a lot of functions that I can't understand signature. Of course I understan that traverse get two arguments, that first is function. However,
what does mean (a -> f b) ? I can understand (a -> b).
Similary, t a, f (t b)
Could you explain it me ?
traverse is a type class-ed function so sadly the behaviour of this function depends on what exactly we choose t to be. This is not dis-similar to >>= or fmap. However there are rules for it's behaviour, just like in those cases. The rules are supposed to capture the idea that traverse takes a function a -> f b, which is an effectful transformation from a to b and lifts it to work on a whole "container" of as, collecting the effects of each of the local transformations.
For example, if we have Maybe a the implementation of traverse would be
traverse f (Just a) = Just <$> f a
traverse f Nothing = pure Nothing
For lists
traverse f [a1, a2, ...] = (:) <$> f a1 <*> ((:) <$> f a2 <*> ...))
Notice how we're taking advantage of the fact that the "effect" f is not only a functor, but applicative so we can take two f-ful computations, f a and f b and smash them together to get f (a, b). Now we want to come up with a few laws explaining that all traverse can do is apply f to the elements and build the original t a back up while collecting the effects on the outside. We say that
traverse Identity = Identity -- We don't lose elements
t . traverse f = traverse (t . f) -- For nicely composing t
traverse (Compose . fmap g . f) = Compose . fmap (traverse g) . traverse f
Now this looks quite complicated but all it's doing is clarifying the meaning of "Basically walks around and applies the local transformation". All this boils down to is that while you cannot just read the signature to understand what traverse does, an OK intuition for the signature is
We get a local, effectful function f :: a -> f b
A functor full of as
We get back a functor full of b gotten by repeatedly applying f, ala fmap
All the effects of f are accumulated so we get f (t b), not just t b.
Remember though, traverse can get used in some weird ways. For example, the lens package is chock-full of using traverse with very strange functors to great effect.
As a quick test, can you figure out how to use a legal traverse to implement fmap for t? That is
fmapOverkill :: Traversable f => (a -> b) -> (f a -> f b)
Or headMay
headMay :: Traversable t => t a -> Maybe a
Both of these are results of the fact that traversable instances also satisfy Functor and Foldable!

Lenses: Composing backwards and (.) in Lens context

I have been reading this article and in one of their section it is stated:
Lenses compose backwards. Can't we make (.) behave like functions?
You're right, we could. We don't for various reasons, but the
intuition is right. Lenses should combine just like functions. One
thing that's important about that is id can either pre- or post-
compose with any lens without affecting it.
What does that mean by Lenses compose backwards ?
Also, what does this mean: Can't we make (.) behave like functions ?
(.) is a function and by using it with Lens does it make (.) to behave like something else ?
The Lens type:
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t
For our illustrative purposes, we can stick to the less general simple lens type, Lens'. The right side then becomes:
forall f. Functor f => (a -> f a) -> s -> f s
Intuitively, (a -> f a) is an operation on a part of a structure of type s, which is promoted to an operation on the whole structure, (s -> f s). (The functor type constructor f is part of the trickery which allows lenses to generalize getters, setters and lots of other things. We do not need to worry about it for now.) In other words:
From the user point of view, a lens allows to, given a whole, focus on a part of it.
Implementation-wise, a lens is a function which takes a function of the part and results in a function of the whole.
(Note how, in the descriptions I just made, "part" and "whole" appear in different orders.)
Now, a lens is a function, and functions can be composed. As we know, (.) has type:
(.) :: (y -> z) -> (x -> y) -> (x -> z)
Let us make the involved types simple lenses (For the sake of clarity, I will drop the constraint and the forall). x becomes a -> f a, y becomes s -> f s and z becomes t -> f t. The specialized type of (.) would then be:
((s -> f s) -> t -> f t) -> ((a -> f a) -> s -> f s) -> ((a -> f a) -> t -> f t)
The lens we get as result has type (a -> f a) -> (t -> f t). So, a composed lens firstLens . secondLens takes an operation on the part focused by secondLens and makes it an operation on the whole structure firstLens aims at. That just happens to match the order in which OO-style field references are composed, which is opposite to the order in which vanilla Haskell record accessors are composed.
You could think of the Getter part of a lens as a function, which you can extract using view. For example, the lens way of writing the fst function is:
view _1 :: (a,b) -> a
Now observe:
view _1 . view _2 :: (c, (a,b)) -> a -- First take the second pair element, then the first
view (_1 . _2) :: ((b,a) ,c) -> a -- This is "backwards" (exactly the opposite order of the above)
For lenses, (.) doesn't behave like it would for functions. For functions, f . g means "first apply g, then f", but for lenses, it means first use the lens f, then use the lens g. Actually, the (.) function is the same for both types, but lens' types make it seem like it's backwards.

Resources