Online Book Reader

Home Category

Learn You a Haskell for Great Good! - Miran Lipovaca [108]

By Root 535 0
the resulting list of two zipped lists has the length of the shorter of the two. If we zip a finite list with an infinite list, the length of the resulting list will always be equal to the length of the finite list.

So how do zip lists work in an applicative style? Well, the ZipList a type doesn’t have a Show instance, so we need to use the getZipList function to extract a raw list from a zip list:

ghci> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100,100]

[101,102,103]

ghci> getZipList $ (+) <$> ZipList [1,2,3] <*> ZipList [100,100..]

[101,102,103]

ghci> getZipList $ max <$> ZipList [1,2,3,4,5,3] <*> ZipList [5,3,1,2]

[5,3,3,4]

ghci> getZipList $ (,,) <$> ZipList "dog" <*> ZipList "cat" <*> ZipList "rat"

[('d','c','r'),('o','a','a'),('g','t','t')]

Note

The (,,) function is the same as \x y z -> (x,y,z). Also, the (,) function is the same as \x y -> (x,y).

Aside from zipWith, the standard library has functions such as zipWith3 and zipWith4, all the way up to zipWith7. zipWith takes a function that takes two parameters and zips two lists with it. zipWith3 takes a function that takes three parameters and zips three lists with it, and so on. By using zip lists with an applicative style, we don’t need to have a separate zip function for each number of lists that we want to zip together. We just use the applicative style to zip together an arbitrary amount of lists with a function, and that’s pretty handy.

Applicative Laws


Like normal functors, applicative functors come with a few laws. The most important law is the one that pure f <*> x = fmap f x holds. As an exercise, you can prove this law for some of the applicative functors that we’ve met in this chapter. The following are the other applicative laws:

pure id <*> v = v

pure (.) <*> u <*> v <*> w = u <*> (v <*> w)

pure f <*> pure x = pure (f x)

u <*> pure y = pure ($ y) <*> u

We won’t go over them in detail because that would take up a lot of pages and be kind of boring. If you’re interested, you can take a closer look at them and see if they hold for some of the instances.

Useful Functions for Applicatives

Control.Applicative defines a function that’s called liftA2, which has the following type:

liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c

It’s defined like this:

liftA2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c

liftA2 f a b = f <$> a <*> b

It just applies a function between two applicatives, hiding the applicative style that we’ve discussed. However, it clearly showcases why applicative functors are more powerful than ordinary functors.

With ordinary functors, we can just map functions over one functor value. With applicative functors, we can apply a function between several functor values. It’s also interesting to look at this function’s type as (a -> b -> c) -> (f a -> f b -> f c). When we look at it like this, we can say that liftA2 takes a normal binary function and promotes it to a function that operates on two applicatives.

Here’s an interesting concept: We can take two applicative values and combine them into one applicative value that has inside it the results of those two applicative values in a list. For instance, we have Just 3 and Just 4. Let’s assume that the second one contains a singleton list, because that’s really easy to achieve:

ghci> fmap (\x -> [x]) (Just 4)

Just [4]

Okay, so let’s say we have Just 3 and Just [4]. How do we get Just [3,4]? That’s easy:

ghci> liftA2 (:) (Just 3) (Just [4])

Just [3,4]

ghci> (:) <$> Just 3 <*> Just [4]

Just [3,4]

Remember that : is a function that takes an element and a list and returns a new list with that element at the beginning. Now that we have Just [3,4], could we combine that with Just 2 to produce Just [2,3,4]? Yes, we could. It seems that we can combine any amount of applicative values into one applicative value that has a list of the results of those applicative values inside it.

Let’s try implementing a function that takes a list of applicative values and returns an applicative value that has a list as

Return Main Page Previous Page Next Page

®Online Book Reader