We know from the category theory that not all endofunctors in Set admit a free monad. The canonical counterexample is the powerset functor.
But Haskell can turn any functor into a free monad.
data Free f a = Pure a | Free (f (Free f a)) instance Functor f => Monad (Free f) where return = Pure Pure a >>= f = f a Free m >>= f = Free ((>>= f) <$> m)
What makes this construction work for any Haskell functor but break down in Set?
Free monads are “free” because they do not impose any additional constraints beyond those required by the definition of a monad. They are a particular type of a free algebraic structure. As such, they are very similar to free monoids. They build tree-like structures, which later can be interpreted.
The free monad is the interpreter's best friend. Free monads "free the interpreter" as much as possible while still maintaining the bare minimum necessary to form a monad. Free monads arise every time an interpreter wants to give the program writer a monad, and nothing more.
A free monad is a construction which allows you to build a monad from any Functor. Like other monads, it is a pure way to represent and manipulate computations. In particular, free monads provide a practical way to: represent stateful computations as data, and run them.
It's become clear that this answer is wrong. I'm leaving it here to preserve valuable discussion in the comments until someone formulates a correct answer.
Consider the power set in Set
. If we have a function f : S -> T
, we can form f' : PS S -> PS T
by f' X = f [X]
. Nice covariant functor (I think). We could also form f'' X = f^(-1) [X]
, a nice contravariant functor (I think).
Let's look at the "power set" in Haskell:
newtype PS t = PS (t -> Bool)
This is not a Functor
, but only a Contravariant
:
instance Contravariant PS where contramap f (PS g) = PS (g . f)
We recognize this because t
is in negative position. Unlike Set
, we cannot get at the "elements" of the characteristic functions that make up the power set, so the covariant functor isn't available.
I would conjecture, therefore, that the reason Haskell admits a free monad for every covariant functor is that it excludes those covariant functors that cause trouble for Set
.
I (rather) have a suspicion that this is not exactly a definition. Say, this recursive formula specifies a fixpoint; now, how do we know this fixpoint exists? How do we know there's only one fixpoint? And more, how does Free m >>=
define anything, except maybe in the case where we assume that we only have finite sequences of applications of Free
?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With