A Haskell "Foldable" quiz
How does GHCi respond to fold [] 42?
Answer
ghci> fold [] 42
()
How does GHCi respond to fold [] 42 == []?
Answer
ghci> fold [] 42 == []
True
What is the type of fold [] 42?
Answer
ghci> :t fold [] 42
fold [] 42 :: Monoid t => t
What the hell is going on!?
Answer
fold has type (Foldable t, Monoid a) => t a -> a, so fold [] has type Monoid a => a.
fold [] is mempty, which means fold [] 42 is equal to mempty 42.
This is well-typed because functions have a Monoid instance.
mempty for functions is const mempty.
So mempty 42 is const mempty 42 is mempty :: Monoid b => b.
In GHCi, b is defaulted to (), which is why the first question prints ().
fold [] 42 == [], the list monoid is chosen instead, reducing to [] == [].
Why am I even thinking about this?
Answer
I just found a bug due to replacing fromMaybe Set.empty (which has type Maybe (Set a) -> Set a) with fold Set.empty (which has type Monoid b => a -> b and is equivalent to const mempty).
This meant that all my Justs containing non-empty sets were being ignored.
fromMaybe Set.empty with fold, which really are the same.