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 Just
s. 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.