Fiddling with Functors

Learn you a Haskell continues to bend my mind. This week we were looking at the first half of the chapter on Functors, Applicative Functors and Monoids. I feel I’m following along with the text okay, but just getting brief glimpses at the strange beasts that that lay beneath. While noodling around with one of the examples

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

I wondered if the type system could infer one of those Justs. Indeed it can

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

Of course, it can’t infer both of them, so what happens when I replace both mentions with pure?

ghci> :t (:) <$> pure 3 <*> pure [4]
(:) <$> pure 3 <*> pure [4] :: (Num a, Applicative f) => f [a]

Hmm, it seems to result in a type with a free Applicative variable. Can I add a type declaration to get back to where we started?

ghci> (:) <$> pure 3 <*> pure [4] :: Num a => Maybe [a]
Just [3,4]

Yup. Now I’ve a neat way to try some of the other instances of Applicative that we’ve been learning about

ghci> (:) <$> pure 3 <*> pure [4] :: Num a => [[a]]
[[3,4]]
ghci> (:) <$> pure 3 <*> pure [4] :: Num a => Either n [a]
Right [3,4]
ghci> (:) <$> pure 3 <*> pure [4] :: Num a => IO [a]
[3,4]

That’s cool, but what about the mysterious (->) r? After a few false starts on the syntax for the type declaration, I can make the type system happy:

ghci> let thing = (:) <$> pure 3 <*> pure [4] :: Num a => r -> [a]

But what is thing?

ghci> :t thing
thing :: r -> [Integer]
ghci> thing 3
[3,4]
ghci> thing (zip)
[3,4]
ghci> thing ([1..1000], "Haha")
[3,4]

So it’s a function of one (ignored) parameter that always returns our list? That’s fine, but (->) r as an Applicative is still mysterious. What’s it for?

Hmm. Hmmmmm. Hmmmmmmmmmm.

Leave a Reply

Your email address will not be published. Required fields are marked *