What are free monads? - haskell

I've seen the term Free Monad pop up every now and then for some time, but everyone just seems to use/discuss them without giving an explanation of what they are. So: what are free monads? (I'd say I'm familiar with monads and the Haskell basics, but have only a very rough knowledge of category theory.)

Here's an even simpler answer: A Monad is something that "computes" when monadic context is collapsed by join :: m (m a) -> m a (recalling that >>= can be defined as x >>= y = join (fmap y x)). This is how Monads carry context through a sequential chain of computations: because at each point in the series, the context from the previous call is collapsed with the next.
A free monad satisfies all the Monad laws, but does not do any collapsing (i.e., computation). It just builds up a nested series of contexts. The user who creates such a free monadic value is responsible for doing something with those nested contexts, so that the meaning of such a composition can be deferred until after the monadic value has been created.

Edward Kmett's answer is obviously great. But, it is a bit technical. Here is a perhaps more accessible explanation.
Free monads are just a general way of turning functors into monads. That is, given any functor f Free f is a monad. This would not be very useful, except you get a pair of functions
liftFree :: Functor f => f a -> Free f a
foldFree :: Functor f => (f r -> r) -> Free f r -> r
the first of these lets you "get into" your monad, and the second one gives you a way to "get out" of it.
More generally, if X is a Y with some extra stuff P, then a "free X" is a a way of getting from a Y to an X without gaining anything extra.
Examples: a monoid (X) is a set (Y) with extra structure (P) that basically says it has an operation (you can think of addition) and some identity (like zero).
So
class Monoid m where
mempty :: m
mappend :: m -> m -> m
Now, we all know lists
data [a] = [] | a : [a]
Well, given any type t we know that [t] is a monoid
instance Monoid [t] where
mempty = []
mappend = (++)
and so lists are the "free monoid" over sets (or in Haskell types).
Okay, so free monads are the same idea. We take a functor, and give back a monad. In fact, since monads can be seen as monoids in the category of endofunctors, the definition of a list
data [a] = [] | a : [a]
looks a lot like the definition of free monads
data Free f a = Pure a | Roll (f (Free f a))
and the Monad instance has a similarity to the Monoid instance for lists
--it needs to be a functor
instance Functor f => Functor (Free f) where
fmap f (Pure a) = Pure (f a)
fmap f (Roll x) = Roll (fmap (fmap f) x)
--this is the same thing as (++) basically
concatFree :: Functor f => Free f (Free f a) -> Free f a
concatFree (Pure x) = x
concatFree (Roll y) = Roll (fmap concatFree y)
instance Functor f => Monad (Free f) where
return = Pure -- just like []
x >>= f = concatFree (fmap f x) --this is the standard concatMap definition of bind
now, we get our two operations
-- this is essentially the same as \x -> [x]
liftFree :: Functor f => f a -> Free f a
liftFree x = Roll (fmap Pure x)
-- this is essentially the same as folding a list
foldFree :: Functor f => (f r -> r) -> Free f r -> r
foldFree _ (Pure a) = a
foldFree f (Roll x) = f (fmap (foldFree f) x)

A free foo happens to be the simplest thing that satisfies all of the 'foo' laws. That is to say it satisfies exactly the laws necessary to be a foo and nothing extra.
A forgetful functor is one that "forgets" part of the structure as it goes from one category to another.
Given functors F : D -> C, and G : C -> D, we say F -| G, F is left adjoint to G, or G is right adjoint to F whenever forall a, b: F a -> b is isomorphic to a -> G b, where the arrows come from the appropriate categories.
Formally, a free functor is left adjoint to a forgetful functor.
The Free Monoid
Let us start with a simpler example, the free monoid.
Take a monoid, which is defined by some carrier set T, a binary function to mash a pair of elements together f :: T → T → T, and a unit :: T, such that you have an associative law, and an identity law: f(unit,x) = x = f(x,unit).
You can make a functor U from the category of monoids (where arrows are monoid homomorphisms, that is, they ensure they map unit to unit on the other monoid, and that you can compose before or after mapping to the other monoid without changing meaning) to the category of sets (where arrows are just function arrows) that 'forgets' about the operation and unit, and just gives you the carrier set.
Then, you can define a functor F from the category of sets back to the category of monoids that is left adjoint to this functor. That functor is the functor that maps a set a to the monoid [a], where unit = [], and mappend = (++).
So to review our example so far, in pseudo-Haskell:
U : Mon → Set -- is our forgetful functor
U (a,mappend,mempty) = a
F : Set → Mon -- is our free functor
F a = ([a],(++),[])
Then to show F is free, we need to demonstrate that it is left adjoint to U, a forgetful functor, that is, as we mentioned above, we need to show that
F a → b is isomorphic to a → U b
now, remember the target of F is in the category Mon of monoids, where arrows are monoid homomorphisms, so we need a to show that a monoid homomorphism from [a] → b can be described precisely by a function from a → b.
In Haskell, we call the side of this that lives in Set (er, Hask, the category of Haskell types that we pretend is Set), just foldMap, which when specialized from Data.Foldable to Lists has type Monoid m => (a → m) → [a] → m.
There are consequences that follow from this being an adjunction. Notably that if you forget then build up with free, then forget again, its just like you forgot once, and we can use this to build up the monadic join. since UFUF ~ U(FUF) ~ UF, and we can pass in the identity monoid homomorphism from [a] to [a] through the isomorphism that defines our adjunction,get that a list isomorphism from [a] → [a] is a function of type a -> [a], and this is just return for lists.
You can compose all of this more directly by describing a list in these terms with:
newtype List a = List (forall b. Monoid b => (a -> b) -> b)
The Free Monad
So what is a Free Monad?
Well, we do the same thing we did before, we start with a forgetful functor U from the category of monads where arrows are monad homomorphisms to a category of endofunctors where the arrows are natural transformations, and we look for a functor that is left adjoint to that.
So, how does this relate to the notion of a free monad as it is usually used?
Knowing that something is a free monad, Free f, tells you that giving a monad homomorphism from Free f -> m, is the same thing (isomorphic to) as giving a natural transformation (a functor homomorphism) from f -> m. Remember F a -> b must be isomorphic to a -> U b for F to be left adjoint to U. U here mapped monads to functors.
F is at least isomorphic to the Free type I use in my free package on hackage.
We could also construct it in tighter analogy to the code above for the free list, by defining
class Algebra f x where
phi :: f x -> x
newtype Free f a = Free (forall x. Algebra f x => (a -> x) -> x)
Cofree Comonads
We can construct something similar, by looking at the right adjoint to a forgetful functor assuming it exists. A cofree functor is simply /right adjoint/ to a forgetful functor, and by symmetry, knowing something is a cofree comonad is the same as knowing that giving a comonad homomorphism from w -> Cofree f is the same thing as giving a natural transformation from w -> f.

The Free Monad (data structure) is to the Monad (class) like the List (data structure) to the Monoid (class): It is the trivial implementation, where you can decide afterwards how the content will be combined.
You probably know what a Monad is and that each Monad needs a specific (Monad-law abiding) implementation of either fmap + join + return or bind + return.
Let us assume you have a Functor (an implementation of fmap) but the rest depends on values and choices made at run-time, which means that you want to be able to use the Monad properties but want to choose the Monad-functions afterwards.
That can be done using the Free Monad (data structure), which wraps the Functor (type) in such a way so that the join is rather a stacking of those functors than a reduction.
The real return and join you want to use, can now be given as parameters to the reduction function foldFree:
foldFree :: Functor f => (a -> b) -> (f b -> b) -> Free f a -> b
foldFree return join :: Monad m => Free m a -> m a
To explain the types, we can replace Functor f with Monad m and b with (m a):
foldFree :: Monad m => (a -> (m a)) -> (m (m a) -> (m a)) -> Free m a -> (m a)

A Haskell free monad is a list of functors. Compare:
data List a = Nil | Cons a (List a )
data Free f r = Pure r | Free (f (Free f r))
Pure is analogous to Nil and Free is analogous to Cons. A free monad stores a list of functors instead of a list of values. Technically, you could implement free monads using a different data type, but any implementation should be isomorphic to the above one.
You use free monads whenever you need an abstract syntax tree. The base functor of the free monad is the shape of each step of the syntax tree.
My post, which somebody already linked, gives several examples of how to build abstract syntax trees with free monads

I think a simple concrete example will help. Suppose we have a functor
data F a = One a | Two a a | Two' a a | Three Int a a a
with the obvious fmap. Then Free F a is the type of trees whose leaves have type a and whose nodes are tagged with One, Two, Two' and Three. One-nodes have one child, Two- and Two'-nodes have two children and Three-nodes have three and are also tagged with an Int.
Free F is a monad. return maps x to the tree that is just a leaf with value x. t >>= f looks at each of the leaves and replaces them with trees. When the leaf has value y it replaces that leaf with the tree f y.
A diagram makes this clearer, but I don't have the facilities for easily drawing one!

Trying to provide a “bridge” answer between the auper-simple answers here and the full answer.
So “free monads” build a “monad” out of any “functor”, so let’s take these in order.
Functors in detail
Some things are type-level adjectives, meaning they take a type-noun like “integers” and give you back a different type-noun like “lists of integers” or “pairs of strings with integers” or even “functions making strings out of integers.” To denote an arbitrary adjective let me use the stand-in word “blue”.
But then we notice a pattern that some of these adjectives are input-ish or output-ish in the noun they modify. For example “functions making strings out of __” is input-ish, “functions turning strings into __” is output-ish. The rule here involves me having a function X → Y, some adjective “blue” is outputtish, or a functor, if I can use such a function to transform a blue X into a blue Y. Think of “a firehose spraying Xs” and then you screw on this X → Y function and now your firehose sprays Ys. Or it is inputtish or a contravariant if it is the opposite, a vacuum cleaner sucking up Ys and when I screw this on I get a vacuum sucking up Xs. Some things are neither outputtish nor inputtish. Things that are both it turns out are phantom: they have absolutely nothing to do with the nouns that they describe, in the sense that you can define a function “coerce” which takes a blue X and makes a blue Y, but *without knowing the details of the types X or Y,” not even requiring a function between them.
So “lists of __” is outputtish, you can map an X → Y over a list of Xs to get a list of Ys. Similarly “a pair of a string and a __” is outputtish. Meanwhile “a function from __ to itself” is neither outputtish nor inputtish,” while “a string and a list of exactly zero __s” could be the “phantom” case maybe.
But yeah, that's all there is to functors in programming, they are just things that are mappable. If something is a functor it is a functor uniquely, there is at most only one way to generically map a function over a data structure.
Monads
A monad is a functor that in addition is both
Universally applicable, given any X, I can construct a blue X,
Can be repeated without changing the meaning much. So a blue-blue X is in some sense the same as just a blue X.
So what this means is that there is a canonical function collapsing any blue-blue __ to just a blue __. (And we of course add laws to make everything sane: if one of the layers of blue came from the universal application, then we want to just erase that universal application; in addition if we flatten a blue-blue-blue X down to a blue X, it should not make a difference whether we collapse the first two blues first or the second two first.)
The first example is “a nullable __”. So if I give you a nullable nullable int, in some sense I have not given you much more than a nullable int. Or “a list of lists of ints,” if the point is just to have 0 or more of them, then “a list of ints” works just fine and the proper collapse is concatenating all of the lists together into one super list.
Monads became big in Haskell because Haskell needed an approach to do things in the real world without violating its mathematically pure world where nothing really happens. The solution was to add is sort of watered down form of metaprogramming where we introduce an adjective of “a program which produces a __.” So how do I fetch the current date? Well, Haskell can't do it directly without unsafePerformIO but it will let you describe and compose the program which produces the current date. In this vision, you are supposed to describe a program which produces nothing called “Main.main,” and the compiler is supposed to take your description and hand you this program as a binary executable for you to run whenever you want.
Anyway “a program which produces a program which produce an int” doesn't buy you much over “a program which produces an int” so this turns out to be a monad.
Free Monads
Unlike functors, monads aren't uniquely monads. There is not just one monad instance for a given functor. So for example “a pair of an int and a __”, what are you doing with that int? You could add it, you could multiply it. If you make it a nullable int, you could keep the minimum non-null one or the maximum non-null one, or the leftmost non-null one or the rightmost non-null one.
The free monad for a given functor is the "boringest” construction, it is just “A free blue X is a bluen X for any n = 0, 1, 2, ...”.
It is universal because a blue⁰ X is just an X. And a free blue free blue X is a bluem bluen X which is just a bluem+n X. It implements “collapse” therefore by not implementing collapse at all, internally the blues are nested arbitrarily.
This also means you can defer exactly which monad you are choosing until a later date, later you can define a function which reduces a blue-blue X to a blue X and collapse all of these to blue0,1 X and then another function from X to blue X gives you blue1 X throughout.

Related

Understanding the use of bind in free monad

I'm trying to get how free monads are working.
During this I get into the monad instance of Free, which is:
data Free f a = Pure a | Free (f (Free f a))
instance (Functor f) => Monad (Free f) where
return = Pure
Pure a >>= k = k a
Free m >>= k = Free ((>>= k) <$> m)
Knowing that
-- k :: a -> Free f b
-- m :: f (Free f a)
-- fmap :: Functor f => (a -> b) -> f a -> f b
-- (>>=) :: Free f a -> (a -> Free f b) -> Free f b
I can't get how this is working
Free ((>>= k) <$> m)
First of all how >>= k is even possible? k is a function and the first argument of >>= is not. It's like it bypasses the first argument and puts k as a second one leaving Free f a -> Free f b
Can anyone help me to get a better understanding of this? Thanks!
I don't know what this Free exactly is, however we both know that
(>>= k) <$> m == fmap (>>= k) m
so if m == f sth, then
fmap (>>= k) m == f ((>>= k) sth) == f (sth >>= k)
so everything seems to typecheck.
As suggested also in a comment, probably the only think you missed is that (.op. y) passes y as second argument to .op., unlike (.op.) y, which passes it as first argument.
I cannot help you with the signatures, but if I read correctly between the lines, you want to understand the signatures in order to understand what bind of a free monad of a functor is supposed to do. That I can explain, and hopefully this will also aid you in understanding the signatures you explicitly ask about.
The free monad of a functor f is a functor in the form of a tree where the values are stored in the Pure a leafs and all nodes have the shape of f. All branches have the same length, determined by the number of iterations of Free (f (Free f a)) you have done before you reach Pure a. For example, a free monad of the pair functor f = (a, a) and ten iterations of Free's will be a (perfect) binary tree of ten levels and 2^10 = 1024 a:s stored in the Pure a leafs. With f taking a type to a pair of that type, each iteration of Free (f (Free f a)) takes one "free monad of the pair functor with branches of length n"-type into a pair of two such types, making it a "free monad of the pair functor with branches of length n+1"-type.
As you know, bind takes a monad of type a and a function from a to a monad of b and produces a monad of type b. The bind of a free monad takes a tree of a:s where the branches have length n and a function from a to trees of b where the branches have length m and produces a tree of b:s where the branches have length n+m, simply by applying the function to the a in each Pure a leaf in the original tree and replacing the it with the resulting b tree. When you used to find a Pure a after you decsended n nodes, instead you will find another m levels of nodes leading to a bunch of b:s. Hence the new branch length of n + m.
As a sidenote, since you are trying to understand free monads: in category theory and adjunctions, free typically means "squeeze out information in all ways allowed from the input and store it". Bind of other monads collapses the information in their output using flat map. For example, bind of the list monad will forget the individual length information of the list of lists produced by its function from the input list. Free monads of a functor f never collapses anything, they just grow to fully accommodate all that is fed into them. The free monad of the list functor would just wrap the list of lists in another level of Free ([(Free [] a)]). This leads us to the other property associated with the term "free": there is a way to get from the free monad of a functor to any other monad of the functor. I'm not entirely sure what that means exactly in this context, though...

What is the relationship between bind and join?

I got the impression that (>>=) (used by Haskell) and join (preferred by mathematicians) are "equal" since one can write one in terms of the other:
import Control.Monad (join)
join x = x >>= id
x >>= f = join (fmap f x)
Additionally every monad is a functor since bind can be used to replace fmap:
fmap f x = x >>= (return . f)
I have the following questions:
Is there a (non-recursive) definition of fmap in terms of join? (fmap f x = join $ fmap (return . f) x follows from the equations above but is recursive.)
Is "every monad is a functor" a conclusion when using bind (in the definition of a monad), but an assumption when using join?
Is bind more "powerful" than join? And what would "more powerful" mean?
A monad can be either defined in terms of:
return :: a -> m a
bind :: m a -> (a -> m b) -> m b
or alternatively in terms of:
return :: a -> m a
fmap :: (a -> b) -> m a -> m b
join :: m (m a) -> m a
To your questions:
No, we cannot define fmap in terms of join, since otherwise we could remove fmap from the second list above.
No, "every monad is a functor" is a statement about monads in general, regardless whether you define your specific monad in terms of bind or in terms of join and fmap. It is easier to understand the statement if you see the second definition, but that's it.
Yes, bind is more "powerful" than join. It is exactly as "powerful" as join and fmap combined, if you mean with "powerful" that it has the capacity to define a monad (always in combination with return).
For an intuition, see e.g. this answer – bind allows you to combine or chain strategies/plans/computations (that are in a context) together. As an example, let's use the Maybe context (or Maybe monad):
λ: let plusOne x = Just (x + 1)
λ: Just 3 >>= plusOne
Just 4
fmap also let's you chain computations in a context together, but at the cost of increasing the nesting with every step.[1]
λ: fmap plusOne (Just 3)
Just (Just 4)
That's why you need join: to squash two levels of nesting into one. Remember:
join :: m (m a) -> m a
Having only the squashing step doesn't get you very far. You need also fmap to have a monad – and return, which is Just in the example above.
[1]: fmap and (>>=) don't take their two arguments in the same order, but don't let that confuse you.
Is there a [definition] of fmap in terms of join?
No, there isn't. That can be demonstrated by attempting to do it. Suppose we are given an arbitrary type constructor T, and functions:
returnT :: a -> T a
joinT :: T (T a) -> T a
From this data alone, we want to define:
fmapT :: (a -> b) -> T a -> T b
So let's sketch it:
fmapT :: (a -> b) -> T a -> T b
fmapT f ta = tb
where
tb = undefined -- tb :: T b
We need to get a value of type T b somehow. ta :: T a on its own won't do, so we need functions that produce T b values. The only two candidates are joinT and returnT. joinT doesn't help:
fmapT :: (a -> b) -> T a -> T b
fmapT f ta = joinT ttb
where
ttb = undefined -- ttb :: T (T b)
It just kicks the can down the road, as needing a T (T b) value under these circumstances is no improvement.
We might try returnT instead:
fmapT :: (a -> b) -> T a -> T b
fmapT f ta = returnT b
where
b = undefined -- b :: b
Now we need a b value. The only thing that can give us one is f:
fmapT :: (a -> b) -> T a -> T b
fmapT f ta = returnT (f a)
where
a = undefined -- a :: a
And now we are stuck: nothing can give us an a. We have exhausted all available possibilities, so fmapT cannot be defined in such terms.
A digression: it wouldn't suffice to cheat by using a function like this:
extractT :: T a -> a
With an extractT, we might try a = extractT ta, leading to:
fmapT :: (a -> b) -> T a -> T b
fmapT f ta = returnT (f (extractT ta))
It is not enough, however, for fmapT to have the right type: it must also follow the functor laws. In particular, fmapT id = id should hold. With this definition, fmapT id is returnT . extractT, which, in general, is not id (most functors which are instances of both Monad and Comonad serve as examples).
Is "every monad is a functor" a conclusion when using bind (in the definition of a monad), but an assumption when using join?
"Every monad is a functor" is an assumption, or, more precisely, part of the definition of monad. To pick an arbitrary illustration, here is Emily Riehl, Category Theory In Context, p. 154:
Definition 5.1.1. A monad on a category C consists of
an endofunctor T : C → C,
a unit natural transformation η : 1C ⇒ T, and
a multiplication natural transformation μ :T2 ⇒ T,
so that the following diagrams commute in CC: [diagrams of the monad laws]
A monad, therefore, involves an endofunctor by definition. For a Haskell type constructor T that instantiates Monad, the object mapping of that endofunctor is T itself, and the morphism mapping is its fmap. That T will be a Functor instance, and therefore will have an fmap, is, in contemporary Haskell, guaranteed by Applicative (and, by extension, Functor) being a superclass of Monad.
Is that the whole story, though? As far as Haskell is concerned. we know that liftM exists, and also that in a not-so-distant past Functor was not a superclass of Monad. Are those two facts mere Haskellisms? Not quite. In the classic paper Notions of computation and monads, Eugenio Moggi unearths the following definition (p. 3):
Definition 1.2 ([Man76]) A Kleisli triple over a category C is a triple (T, η, _*), where T : Obj(C) → Obj(C), ηA : A → T A for A ∈ Obj(C), f* : T A → T B for f : A → T B and the following equations hold:
ηA* = idT A
ηA; f* = f   for   f : A → T B
f*; g* = (f; g*)*   for   f : A → T B   and   g : B → T C
The important detail here is that T is presented as merely an object mapping in the category C, and not as an endofunctor in C. Working in the Hask category, that amounts to taking a type constructor T without presupposing it is a Functor instance. In code, we might write that as:
class KleisliTriple t where
return :: a -> t a
(=<<) :: (a -> t b) -> t a -> t b
-- (return =<<) = id
-- (f =<<) . return = f
-- (g =<<) . (f =<<) = ((g =<<) . f =<<)
Flipped bind aside, that is the pre-AMP definition of Monad in Haskell. Unsurprisingly, Moggi's paper doesn't take long to show that "there is a one-to-one correspondence between Kleisli triples and monads" (p. 5), establishing along the way that T can be extended to an endofunctor (in Haskell, that step amounts to defining the morphism mapping liftM f m = return . f =<< m, and then showing it follows the functor laws).
All in all, if you write lawful definitions of return and (>>=) without presupposing fmap, you indeed get a lawful implementation of Functor as a consequence. "There is a one-to-one correspondence between Kleisli triples and monads" is a consequence of the definition of Kleisli triple, while "a monad involves an endofunctor" is part of the definition of monad. It is tempting to consider whether it would be more accurate to describe what Haskellers did when writing Monad instances as "setting up a Klesili triple" rather than "setting up a monad", but I will refrain out of fear of getting mired down terminological pedantry -- and in any case, now that Functor is a superclass of Monad there is no practical reason to worry about that.
Is bind more "powerful" than join? And what would "more powerful" mean?
Trick question!
Taken at face value, the answer would be yes, to the extent that, together with return, (>>=) makes it possible to implement fmap (via liftM, as noted above), while join doesn't. However, I don't feel it is worthwhile to insist on this distinction. Why so? Because of the monad laws. Just like it doesn't make sense to talk about a lawful (>>=) without presupposing return, it doesn't make sense to talk about a lawful join without pressuposing return and fmap.
One might get the impression that I am giving too much weight to the laws by using them to tie Monad and Functor in this way. It is true that there are cases of laws that involve two classes, and that only apply to types which instantiate them both. Foldable provides a good example of that: we can find the following law in the Traversable documentation:
The superclass instances should satisfy the following: [...]
In the Foldable instance, foldMap should be equivalent to traversal with a constant applicative functor (foldMapDefault).
That this specific law doesn't always apply is not a problem, because we don't need it to characterise what Foldable is (alternatives include "a Foldable is a container from which we can extract some sequence of elements", and "a Foldable is a container that can be converted to the free monoid on its element type"). With the monad laws, though, it isn't like that: the meaning of the class is inextricably bound to all three of the monad laws.

Understanding differences between functors, applicative functors and monads? [duplicate]

While explaining to someone what a type class X is I struggle to find good examples of data structures which are exactly X.
So, I request examples for:
A type constructor which is not a Functor.
A type constructor which is a Functor, but not Applicative.
A type constructor which is an Applicative, but is not a Monad.
A type constructor which is a Monad.
I think there are plenty examples of Monad everywhere, but a good example of Monad with some relation to previous examples could complete the picture.
I look for examples which would be similar to each other, differing only in aspects important for belonging to the particular type class.
If one could manage to sneak up an example of Arrow somewhere in this hierarchy (is it between Applicative and Monad?), that would be great too!
A type constructor which is not a Functor:
newtype T a = T (a -> Int)
You can make a contravariant functor out of it, but not a (covariant) functor. Try writing fmap and you'll fail. Note that the contravariant functor version is reversed:
fmap :: Functor f => (a -> b) -> f a -> f b
contramap :: Contravariant f => (a -> b) -> f b -> f a
A type constructor which is a functor, but not Applicative:
I don't have a good example. There is Const, but ideally I'd like a concrete non-Monoid and I can't think of any. All types are basically numeric, enumerations, products, sums, or functions when you get down to it. You can see below pigworker and I disagreeing about whether Data.Void is a Monoid;
instance Monoid Data.Void where
mempty = undefined
mappend _ _ = undefined
mconcat _ = undefined
Since _|_ is a legal value in Haskell, and in fact the only legal value of Data.Void, this meets the Monoid rules. I am unsure what unsafeCoerce has to do with it, because your program is no longer guaranteed not to violate Haskell semantics as soon as you use any unsafe function.
See the Haskell Wiki for an article on bottom (link) or unsafe functions (link).
I wonder if it is possible to create such a type constructor using a richer type system, such as Agda or Haskell with various extensions.
A type constructor which is an Applicative, but not a Monad:
newtype T a = T {multidimensional array of a}
You can make an Applicative out of it, with something like:
mkarray [(+10), (+100), id] <*> mkarray [1, 2]
== mkarray [[11, 101, 1], [12, 102, 2]]
But if you make it a monad, you could get a dimension mismatch. I suspect that examples like this are rare in practice.
A type constructor which is a Monad:
[]
About Arrows:
Asking where an Arrow lies on this hierarchy is like asking what kind of shape "red" is. Note the kind mismatch:
Functor :: * -> *
Applicative :: * -> *
Monad :: * -> *
but,
Arrow :: * -> * -> *
My style may be cramped by my phone, but here goes.
newtype Not x = Kill {kill :: x -> Void}
cannot be a Functor. If it were, we'd have
kill (fmap (const ()) (Kill id)) () :: Void
and the Moon would be made of green cheese.
Meanwhile
newtype Dead x = Oops {oops :: Void}
is a functor
instance Functor Dead where
fmap f (Oops corpse) = Oops corpse
but cannot be applicative, or we'd have
oops (pure ()) :: Void
and Green would be made of Moon cheese (which can actually happen, but only later in the evening).
(Extra note: Void, as in Data.Void is an empty datatype. If you try to use undefined to prove it's a Monoid, I'll use unsafeCoerce to prove that it isn't.)
Joyously,
newtype Boo x = Boo {boo :: Bool}
is applicative in many ways, e.g., as Dijkstra would have it,
instance Applicative Boo where
pure _ = Boo True
Boo b1 <*> Boo b2 = Boo (b1 == b2)
but it cannot be a Monad. To see why not, observe that return must be constantly Boo True or Boo False, and hence that
join . return == id
cannot possibly hold.
Oh yeah, I nearly forgot
newtype Thud x = The {only :: ()}
is a Monad. Roll your own.
Plane to catch...
I believe the other answers missed some simple and common examples:
A type constructor which is a Functor but not an Applicative. A simple example is a pair:
instance Functor ((,) r) where
fmap f (x,y) = (x, f y)
But there is no way how to define its Applicative instance without imposing additional restrictions on r. In particular, there is no way how to define pure :: a -> (r, a) for an arbitrary r.
A type constructor which is an Applicative, but is not a Monad. A well-known example is ZipList. (It's a newtype that wraps lists and provides different Applicative instance for them.)
fmap is defined in the usual way. But pure and <*> are defined as
pure x = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)
so pure creates an infinite list by repeating the given value, and <*> zips a list of functions with a list of values - applies i-th function to i-th element. (The standard <*> on [] produces all possible combinations of applying i-th function to j-th element.) But there is no sensible way how to define a monad (see this post).
How arrows fit into the functor/applicative/monad hierarchy?
See Idioms are oblivious, arrows are meticulous, monads are promiscuous by Sam Lindley, Philip Wadler, Jeremy Yallop. MSFP 2008. (They call applicative functors idioms.) The abstract:
We revisit the connection between three notions of computation: Moggi's monads, Hughes's arrows and McBride and Paterson's idioms (also called applicative functors). We show that idioms are equivalent to arrows that satisfy the type isomorphism A ~> B = 1 ~> (A -> B) and that monads are equivalent to arrows that satisfy the type isomorphism A ~> B = A -> (1 ~> B). Further, idioms embed into arrows and arrows embed into monads.
A good example for a type constructor which is not a functor is Set: You can't implement fmap :: (a -> b) -> f a -> f b, because without an additional constraint Ord b you can't construct f b.
I'd like to propose a more systematic approach to answering this question, and also to show examples that do not use any special tricks like the "bottom" values or infinite data types or anything like that.
When do type constructors fail to have type class instances?
In general, there are two reasons why a type constructor could fail to have an instance of a certain type class:
Cannot implement the type signatures of the required methods from the type class.
Can implement the type signatures but cannot satisfy the required laws.
Examples of the first kind are easier than those of the second kind because for the first kind, we just need to check whether one can implement a function with a given type signature, while for the second kind, we are required to prove that no implementation could possibly satisfy the laws.
Specific examples
A type constructor that cannot have a functor instance because the type cannot be implemented:
data F z a = F (a -> z)
This is a contrafunctor, not a functor, with respect to the type parameter a, because a in a contravariant position. It is impossible to implement a function with type signature (a -> b) -> F z a -> F z b.
A type constructor that is not a lawful functor even though the type signature of fmap can be implemented:
data Q a = Q(a -> Int, a)
fmap :: (a -> b) -> Q a -> Q b
fmap f (Q(g, x)) = Q(\_ -> g x, f x) -- this fails the functor laws!
The curious aspect of this example is that we can implement fmap of the correct type even though F cannot possibly be a functor because it uses a in a contravariant position. So this implementation of fmap shown above is misleading - even though it has the correct type signature (I believe this is the only possible implementation of that type signature), the functor laws are not satisfied. For example, fmap id ≠ id, because let (Q(f,_)) = fmap id (Q(read,"123")) in f "456" is 123, but let (Q(f,_)) = id (Q(read,"123")) in f "456" is 456.
In fact, F is only a profunctor, - it is neither a functor nor a contrafunctor.
A lawful functor that is not applicative because the type signature of pure cannot be implemented: take the Writer monad (a, w) and remove the constraint that w should be a monoid. It is then impossible to construct a value of type (a, w) out of a.
A functor that is not applicative because the type signature of <*> cannot be implemented: data F a = Either (Int -> a) (String -> a).
A functor that is not lawful applicative even though the type class methods can be implemented:
data P a = P ((a -> Int) -> Maybe a)
The type constructor P is a functor because it uses a only in covariant positions.
instance Functor P where
fmap :: (a -> b) -> P a -> P b
fmap fab (P pa) = P (\q -> fmap fab $ pa (q . fab))
The only possible implementation of the type signature of <*> is a function that always returns Nothing:
(<*>) :: P (a -> b) -> P a -> P b
(P pfab) <*> (P pa) = \_ -> Nothing -- fails the laws!
But this implementation does not satisfy the identity law for applicative functors.
A functor that is Applicative but not a Monad because the type signature of bind cannot be implemented.
I do not know any such examples!
A functor that is Applicative but not a Monad because laws cannot be satisfied even though the type signature of bind can be implemented.
This example has generated quite a bit of discussion, so it is safe to say that proving this example correct is not easy. But several people have verified this independently by different methods. See Is `data PoE a = Empty | Pair a a` a monad? for additional discussion.
data B a = Maybe (a, a)
deriving Functor
instance Applicative B where
pure x = Just (x, x)
b1 <*> b2 = case (b1, b2) of
(Just (x1, y1), Just (x2, y2)) -> Just((x1, x2), (y1, y2))
_ -> Nothing
It is somewhat cumbersome to prove that there is no lawful Monad instance. The reason for the non-monadic behavior is that there is no natural way of implementing bind when a function f :: a -> B b could return Nothing or Just for different values of a.
It is perhaps clearer to consider Maybe (a, a, a), which is also not a monad, and to try implementing join for that. One will find that there is no intuitively reasonable way of implementing join.
join :: Maybe (Maybe (a, a, a), Maybe (a, a, a), Maybe (a, a, a)) -> Maybe (a, a, a)
join Nothing = Nothing
join Just (Nothing, Just (x1,x2,x3), Just (y1,y2,y3)) = ???
join Just (Just (x1,x2,x3), Nothing, Just (y1,y2,y3)) = ???
-- etc.
In the cases indicated by ???, it seems clear that we cannot produce Just (z1, z2, z3) in any reasonable and symmetric manner out of six different values of type a. We could certainly choose some arbitrary subset of these six values, -- for instance, always take the first nonempty Maybe - but this would not satisfy the laws of the monad. Returning Nothing will also not satisfy the laws.
A tree-like data structure that is not a monad even though it has associativity for bind - but fails the identity laws.
The usual tree-like monad (or "a tree with functor-shaped branches") is defined as
data Tr f a = Leaf a | Branch (f (Tr f a))
This is a free monad over the functor f. The shape of the data is a tree where each branch point is a "functor-ful" of subtrees. The standard binary tree would be obtained with type f a = (a, a).
If we modify this data structure by making also the leaves in the shape of the functor f, we obtain what I call a "semimonad" - it has bind that satisfies the naturality and the associativity laws, but its pure method fails one of the identity laws. "Semimonads are semigroups in the category of endofunctors, what's the problem?" This is the type class Bind.
For simplicity, I define the join method instead of bind:
data Trs f a = Leaf (f a) | Branch (f (Trs f a))
join :: Trs f (Trs f a) -> Trs f a
join (Leaf ftrs) = Branch ftrs
join (Branch ftrstrs) = Branch (fmap #f join ftrstrs)
The branch grafting is standard, but the leaf grafting is non-standard and produces a Branch. This is not a problem for the associativity law but breaks one of the identity laws.
When do polynomial types have monad instances?
Neither of the functors Maybe (a, a) and Maybe (a, a, a) can be given a lawful Monad instance, although they are obviously Applicative.
These functors have no tricks - no Void or bottom anywhere, no tricky laziness/strictness, no infinite structures, and no type class constraints. The Applicative instance is completely standard. The functions return and bind can be implemented for these functors but will not satisfy the laws of the monad. In other words, these functors are not monads because a specific structure is missing (but it is not easy to understand what exactly is missing). As an example, a small change in the functor can make it into a monad: data Maybe a = Nothing | Just a is a monad. Another similar functor data P12 a = Either a (a, a) is also a monad.
Constructions for polynomial monads
In general, here are some constructions that produce lawful Monads out of polynomial types. In all these constructions, M is a monad:
type M a = Either c (w, a) where w is any monoid
type M a = m (Either c (w, a)) where m is any monad and w is any monoid
type M a = (m1 a, m2 a) where m1 and m2 are any monads
type M a = Either a (m a) where m is any monad
The first construction is WriterT w (Either c), the second construction is WriterT w (EitherT c m). The third construction is a component-wise product of monads: pure #M is defined as the component-wise product of pure #m1 and pure #m2, and join #M is defined by omitting cross-product data (e.g. m1 (m1 a, m2 a) is mapped to m1 (m1 a) by omitting the second part of the tuple):
join :: (m1 (m1 a, m2 a), m2 (m1 a, m2 a)) -> (m1 a, m2 a)
join (m1x, m2x) = (join #m1 (fmap fst m1x), join #m2 (fmap snd m2x))
The fourth construction is defined as
data M m a = Either a (m a)
instance Monad m => Monad M m where
pure x = Left x
join :: Either (M m a) (m (M m a)) -> M m a
join (Left mma) = mma
join (Right me) = Right $ join #m $ fmap #m squash me where
squash :: M m a -> m a
squash (Left x) = pure #m x
squash (Right ma) = ma
I have checked that all four constructions produce lawful monads.
I conjecture that there are no other constructions for polynomial monads. For example, the functor Maybe (Either (a, a) (a, a, a, a)) is not obtained through any of these constructions and so is not monadic. However, Either (a, a) (a, a, a) is monadic because it is isomorphic to the product of three monads a, a, and Maybe a. Also, Either (a,a) (a,a,a,a) is monadic because it is isomorphic to the product of a and Either a (a, a, a).
The four constructions shown above will allow us to obtain any sum of any number of products of any number of a's, for example Either (Either (a, a) (a, a, a, a)) (a, a, a, a, a)) and so on. All such type constructors will have (at least one) Monad instance.
It remains to be seen, of course, what use cases might exist for such monads. Another issue is that the Monad instances derived via constructions 1-4 are in general not unique. For example, the type constructor type F a = Either a (a, a) can be given a Monad instance in two ways: by construction 4 using the monad (a, a), and by construction 3 using the type isomorphism Either a (a, a) = (a, Maybe a). Again, finding use cases for these implementations is not immediately obvious.
A question remains - given an arbitrary polynomial data type, how to recognize whether it has a Monad instance. I do not know how to prove that there are no other constructions for polynomial monads. I don't think any theory exists so far to answer this question.

What's a good example for a Haskell functor that is not an applicative functor? [duplicate]

While explaining to someone what a type class X is I struggle to find good examples of data structures which are exactly X.
So, I request examples for:
A type constructor which is not a Functor.
A type constructor which is a Functor, but not Applicative.
A type constructor which is an Applicative, but is not a Monad.
A type constructor which is a Monad.
I think there are plenty examples of Monad everywhere, but a good example of Monad with some relation to previous examples could complete the picture.
I look for examples which would be similar to each other, differing only in aspects important for belonging to the particular type class.
If one could manage to sneak up an example of Arrow somewhere in this hierarchy (is it between Applicative and Monad?), that would be great too!
A type constructor which is not a Functor:
newtype T a = T (a -> Int)
You can make a contravariant functor out of it, but not a (covariant) functor. Try writing fmap and you'll fail. Note that the contravariant functor version is reversed:
fmap :: Functor f => (a -> b) -> f a -> f b
contramap :: Contravariant f => (a -> b) -> f b -> f a
A type constructor which is a functor, but not Applicative:
I don't have a good example. There is Const, but ideally I'd like a concrete non-Monoid and I can't think of any. All types are basically numeric, enumerations, products, sums, or functions when you get down to it. You can see below pigworker and I disagreeing about whether Data.Void is a Monoid;
instance Monoid Data.Void where
mempty = undefined
mappend _ _ = undefined
mconcat _ = undefined
Since _|_ is a legal value in Haskell, and in fact the only legal value of Data.Void, this meets the Monoid rules. I am unsure what unsafeCoerce has to do with it, because your program is no longer guaranteed not to violate Haskell semantics as soon as you use any unsafe function.
See the Haskell Wiki for an article on bottom (link) or unsafe functions (link).
I wonder if it is possible to create such a type constructor using a richer type system, such as Agda or Haskell with various extensions.
A type constructor which is an Applicative, but not a Monad:
newtype T a = T {multidimensional array of a}
You can make an Applicative out of it, with something like:
mkarray [(+10), (+100), id] <*> mkarray [1, 2]
== mkarray [[11, 101, 1], [12, 102, 2]]
But if you make it a monad, you could get a dimension mismatch. I suspect that examples like this are rare in practice.
A type constructor which is a Monad:
[]
About Arrows:
Asking where an Arrow lies on this hierarchy is like asking what kind of shape "red" is. Note the kind mismatch:
Functor :: * -> *
Applicative :: * -> *
Monad :: * -> *
but,
Arrow :: * -> * -> *
My style may be cramped by my phone, but here goes.
newtype Not x = Kill {kill :: x -> Void}
cannot be a Functor. If it were, we'd have
kill (fmap (const ()) (Kill id)) () :: Void
and the Moon would be made of green cheese.
Meanwhile
newtype Dead x = Oops {oops :: Void}
is a functor
instance Functor Dead where
fmap f (Oops corpse) = Oops corpse
but cannot be applicative, or we'd have
oops (pure ()) :: Void
and Green would be made of Moon cheese (which can actually happen, but only later in the evening).
(Extra note: Void, as in Data.Void is an empty datatype. If you try to use undefined to prove it's a Monoid, I'll use unsafeCoerce to prove that it isn't.)
Joyously,
newtype Boo x = Boo {boo :: Bool}
is applicative in many ways, e.g., as Dijkstra would have it,
instance Applicative Boo where
pure _ = Boo True
Boo b1 <*> Boo b2 = Boo (b1 == b2)
but it cannot be a Monad. To see why not, observe that return must be constantly Boo True or Boo False, and hence that
join . return == id
cannot possibly hold.
Oh yeah, I nearly forgot
newtype Thud x = The {only :: ()}
is a Monad. Roll your own.
Plane to catch...
I believe the other answers missed some simple and common examples:
A type constructor which is a Functor but not an Applicative. A simple example is a pair:
instance Functor ((,) r) where
fmap f (x,y) = (x, f y)
But there is no way how to define its Applicative instance without imposing additional restrictions on r. In particular, there is no way how to define pure :: a -> (r, a) for an arbitrary r.
A type constructor which is an Applicative, but is not a Monad. A well-known example is ZipList. (It's a newtype that wraps lists and provides different Applicative instance for them.)
fmap is defined in the usual way. But pure and <*> are defined as
pure x = ZipList (repeat x)
ZipList fs <*> ZipList xs = ZipList (zipWith id fs xs)
so pure creates an infinite list by repeating the given value, and <*> zips a list of functions with a list of values - applies i-th function to i-th element. (The standard <*> on [] produces all possible combinations of applying i-th function to j-th element.) But there is no sensible way how to define a monad (see this post).
How arrows fit into the functor/applicative/monad hierarchy?
See Idioms are oblivious, arrows are meticulous, monads are promiscuous by Sam Lindley, Philip Wadler, Jeremy Yallop. MSFP 2008. (They call applicative functors idioms.) The abstract:
We revisit the connection between three notions of computation: Moggi's monads, Hughes's arrows and McBride and Paterson's idioms (also called applicative functors). We show that idioms are equivalent to arrows that satisfy the type isomorphism A ~> B = 1 ~> (A -> B) and that monads are equivalent to arrows that satisfy the type isomorphism A ~> B = A -> (1 ~> B). Further, idioms embed into arrows and arrows embed into monads.
A good example for a type constructor which is not a functor is Set: You can't implement fmap :: (a -> b) -> f a -> f b, because without an additional constraint Ord b you can't construct f b.
I'd like to propose a more systematic approach to answering this question, and also to show examples that do not use any special tricks like the "bottom" values or infinite data types or anything like that.
When do type constructors fail to have type class instances?
In general, there are two reasons why a type constructor could fail to have an instance of a certain type class:
Cannot implement the type signatures of the required methods from the type class.
Can implement the type signatures but cannot satisfy the required laws.
Examples of the first kind are easier than those of the second kind because for the first kind, we just need to check whether one can implement a function with a given type signature, while for the second kind, we are required to prove that no implementation could possibly satisfy the laws.
Specific examples
A type constructor that cannot have a functor instance because the type cannot be implemented:
data F z a = F (a -> z)
This is a contrafunctor, not a functor, with respect to the type parameter a, because a in a contravariant position. It is impossible to implement a function with type signature (a -> b) -> F z a -> F z b.
A type constructor that is not a lawful functor even though the type signature of fmap can be implemented:
data Q a = Q(a -> Int, a)
fmap :: (a -> b) -> Q a -> Q b
fmap f (Q(g, x)) = Q(\_ -> g x, f x) -- this fails the functor laws!
The curious aspect of this example is that we can implement fmap of the correct type even though F cannot possibly be a functor because it uses a in a contravariant position. So this implementation of fmap shown above is misleading - even though it has the correct type signature (I believe this is the only possible implementation of that type signature), the functor laws are not satisfied. For example, fmap id ≠ id, because let (Q(f,_)) = fmap id (Q(read,"123")) in f "456" is 123, but let (Q(f,_)) = id (Q(read,"123")) in f "456" is 456.
In fact, F is only a profunctor, - it is neither a functor nor a contrafunctor.
A lawful functor that is not applicative because the type signature of pure cannot be implemented: take the Writer monad (a, w) and remove the constraint that w should be a monoid. It is then impossible to construct a value of type (a, w) out of a.
A functor that is not applicative because the type signature of <*> cannot be implemented: data F a = Either (Int -> a) (String -> a).
A functor that is not lawful applicative even though the type class methods can be implemented:
data P a = P ((a -> Int) -> Maybe a)
The type constructor P is a functor because it uses a only in covariant positions.
instance Functor P where
fmap :: (a -> b) -> P a -> P b
fmap fab (P pa) = P (\q -> fmap fab $ pa (q . fab))
The only possible implementation of the type signature of <*> is a function that always returns Nothing:
(<*>) :: P (a -> b) -> P a -> P b
(P pfab) <*> (P pa) = \_ -> Nothing -- fails the laws!
But this implementation does not satisfy the identity law for applicative functors.
A functor that is Applicative but not a Monad because the type signature of bind cannot be implemented.
I do not know any such examples!
A functor that is Applicative but not a Monad because laws cannot be satisfied even though the type signature of bind can be implemented.
This example has generated quite a bit of discussion, so it is safe to say that proving this example correct is not easy. But several people have verified this independently by different methods. See Is `data PoE a = Empty | Pair a a` a monad? for additional discussion.
data B a = Maybe (a, a)
deriving Functor
instance Applicative B where
pure x = Just (x, x)
b1 <*> b2 = case (b1, b2) of
(Just (x1, y1), Just (x2, y2)) -> Just((x1, x2), (y1, y2))
_ -> Nothing
It is somewhat cumbersome to prove that there is no lawful Monad instance. The reason for the non-monadic behavior is that there is no natural way of implementing bind when a function f :: a -> B b could return Nothing or Just for different values of a.
It is perhaps clearer to consider Maybe (a, a, a), which is also not a monad, and to try implementing join for that. One will find that there is no intuitively reasonable way of implementing join.
join :: Maybe (Maybe (a, a, a), Maybe (a, a, a), Maybe (a, a, a)) -> Maybe (a, a, a)
join Nothing = Nothing
join Just (Nothing, Just (x1,x2,x3), Just (y1,y2,y3)) = ???
join Just (Just (x1,x2,x3), Nothing, Just (y1,y2,y3)) = ???
-- etc.
In the cases indicated by ???, it seems clear that we cannot produce Just (z1, z2, z3) in any reasonable and symmetric manner out of six different values of type a. We could certainly choose some arbitrary subset of these six values, -- for instance, always take the first nonempty Maybe - but this would not satisfy the laws of the monad. Returning Nothing will also not satisfy the laws.
A tree-like data structure that is not a monad even though it has associativity for bind - but fails the identity laws.
The usual tree-like monad (or "a tree with functor-shaped branches") is defined as
data Tr f a = Leaf a | Branch (f (Tr f a))
This is a free monad over the functor f. The shape of the data is a tree where each branch point is a "functor-ful" of subtrees. The standard binary tree would be obtained with type f a = (a, a).
If we modify this data structure by making also the leaves in the shape of the functor f, we obtain what I call a "semimonad" - it has bind that satisfies the naturality and the associativity laws, but its pure method fails one of the identity laws. "Semimonads are semigroups in the category of endofunctors, what's the problem?" This is the type class Bind.
For simplicity, I define the join method instead of bind:
data Trs f a = Leaf (f a) | Branch (f (Trs f a))
join :: Trs f (Trs f a) -> Trs f a
join (Leaf ftrs) = Branch ftrs
join (Branch ftrstrs) = Branch (fmap #f join ftrstrs)
The branch grafting is standard, but the leaf grafting is non-standard and produces a Branch. This is not a problem for the associativity law but breaks one of the identity laws.
When do polynomial types have monad instances?
Neither of the functors Maybe (a, a) and Maybe (a, a, a) can be given a lawful Monad instance, although they are obviously Applicative.
These functors have no tricks - no Void or bottom anywhere, no tricky laziness/strictness, no infinite structures, and no type class constraints. The Applicative instance is completely standard. The functions return and bind can be implemented for these functors but will not satisfy the laws of the monad. In other words, these functors are not monads because a specific structure is missing (but it is not easy to understand what exactly is missing). As an example, a small change in the functor can make it into a monad: data Maybe a = Nothing | Just a is a monad. Another similar functor data P12 a = Either a (a, a) is also a monad.
Constructions for polynomial monads
In general, here are some constructions that produce lawful Monads out of polynomial types. In all these constructions, M is a monad:
type M a = Either c (w, a) where w is any monoid
type M a = m (Either c (w, a)) where m is any monad and w is any monoid
type M a = (m1 a, m2 a) where m1 and m2 are any monads
type M a = Either a (m a) where m is any monad
The first construction is WriterT w (Either c), the second construction is WriterT w (EitherT c m). The third construction is a component-wise product of monads: pure #M is defined as the component-wise product of pure #m1 and pure #m2, and join #M is defined by omitting cross-product data (e.g. m1 (m1 a, m2 a) is mapped to m1 (m1 a) by omitting the second part of the tuple):
join :: (m1 (m1 a, m2 a), m2 (m1 a, m2 a)) -> (m1 a, m2 a)
join (m1x, m2x) = (join #m1 (fmap fst m1x), join #m2 (fmap snd m2x))
The fourth construction is defined as
data M m a = Either a (m a)
instance Monad m => Monad M m where
pure x = Left x
join :: Either (M m a) (m (M m a)) -> M m a
join (Left mma) = mma
join (Right me) = Right $ join #m $ fmap #m squash me where
squash :: M m a -> m a
squash (Left x) = pure #m x
squash (Right ma) = ma
I have checked that all four constructions produce lawful monads.
I conjecture that there are no other constructions for polynomial monads. For example, the functor Maybe (Either (a, a) (a, a, a, a)) is not obtained through any of these constructions and so is not monadic. However, Either (a, a) (a, a, a) is monadic because it is isomorphic to the product of three monads a, a, and Maybe a. Also, Either (a,a) (a,a,a,a) is monadic because it is isomorphic to the product of a and Either a (a, a, a).
The four constructions shown above will allow us to obtain any sum of any number of products of any number of a's, for example Either (Either (a, a) (a, a, a, a)) (a, a, a, a, a)) and so on. All such type constructors will have (at least one) Monad instance.
It remains to be seen, of course, what use cases might exist for such monads. Another issue is that the Monad instances derived via constructions 1-4 are in general not unique. For example, the type constructor type F a = Either a (a, a) can be given a Monad instance in two ways: by construction 4 using the monad (a, a), and by construction 3 using the type isomorphism Either a (a, a) = (a, Maybe a). Again, finding use cases for these implementations is not immediately obvious.
A question remains - given an arbitrary polynomial data type, how to recognize whether it has a Monad instance. I do not know how to prove that there are no other constructions for polynomial monads. I don't think any theory exists so far to answer this question.

Computation Constructs (Monads, Arrows, etc.)

I have become rather interested in how computation is modeled in Haskell. Several resources have described monads as "composable computation" and arrows as "abstract views of computation". I've never seen monoids, functors or applicative functors described in this way. It seems that they lack the necessary structure.
I find that idea interesting and wonder if there are any other constructs that do something similar. If so, what are some resources that I can use to acquaint myself with them? Are there any packages on Hackage that might come in handy?
Note: This question is similar to
Monads vs. Arrows and https://stackoverflow.com/questions/2395715/resources-for-learning-monads-functors-monoids-arrows-etc, but I am looking for constructs beyond funtors, applicative functors, monads, and arrows.
Edit: I concede that applicative functors should be considered "computational constructs", but I'm really looking for something I haven't come across yet. This includes applicative functors, monads and arrows.
Arrows are generalized by Categories, and so by the Category typeclass.
class Category f where
(.) :: f a b -> f b c -> f a c
id :: f a a
The Arrow typeclass definition has Category as a superclass. Categories (in the haskell sense) generalize functions (you can compose them but not apply them) and so are definitely a "model of computation". Arrow provides a Category with additional structure for working with tuples. So, while Category mirrors something about Haskell's function space, Arrow extends that to something about product types.
Every Monad gives rise to something called a "Kleisli Category" and this construction gives you instances of ArrowApply. You can build a Monad out of any ArrowApply such that going full circle doesn't change your behavior, so in some deep sense Monad and ArrowApply are the same thing.
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)
instance Monad m => Arrow (Kleisli m) where
arr f = Kleisli (return . f)
first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d))
second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
Actually every Arrow gives rise to an Applicative (universally quantified to get the kinds right) in addition to the Category superclass, and I believe the combination of the appropriate Category and Applicative is enough to reconstruct your Arrow.
So, these structures are deeply connected.
Warning: wishy-washy commentary ahead. One central difference between the Functor/Applicative/Monad way of thinking and the Category/Arrow way of thinking is that while Functor and its ilk are generalizations at the level of object (types in Haskell), Category/Arrow are generelazation of the notion of morphism (functions in Haskell). My belief is that thinking at the level of generalized morphism involves a higher level of abstraction than thinking at the level of generalized objects. Sometimes that is a good thing, other times it is not. On the other-hand, despite the fact that Arrows have a categorical basis, and no one in math thinks Applicative is interesting, it is my understanding that Applicative is generally better understood than Arrow.
Basically you can think of "Category < Arrow < ArrowApply" and "Functor < Applicative < Monad" such that "Category ~ Functor", "Arrow ~ Applicative" and "ArrowApply ~ Monad".
More Concrete Below:
As for other structures to model computation: one can often reverse the direction of the "arrows" (just meaning morphisms here) in categorical constructions to get the "dual" or "co-construction". So, if a monad is defined as
class Functor m => Monad m where
return :: a -> m a
join :: m (m a) -> m a
(okay, I know that isn't how Haskell defines things, but ma >>= f = join $ fmap f ma and join x = x >>= id so it just as well could be)
then the comonad is
class Functor m => Comonad m where
extract :: m a -> a -- this is co-return
duplicate :: m a -> m (m a) -- this is co-join
This thing turns out to be pretty common also. It turns out that Comonad is the basic underlying structure of cellular automata. For completness, I should point out that Edward Kmett's Control.Comonad puts duplicate in a class between functor and Comonad for "Extendable Functors" because you can also define
extend :: (m a -> b) -> m a -> m b -- Looks familiar? this is just the dual of >>=
extend f = fmap f . duplicate
--this is enough
duplicate = extend id
It turns out that all Monads are also "Extendable"
monadDuplicate :: Monad m => m a -> m (m a)
monadDuplicate = return
while all Comonads are "Joinable"
comonadJoin :: Comonad m => m (m a) -> m a
comonadJoin = extract
so these structures are very close together.
All Monads are Arrows (Monad is isomorphic to ArrowApply). In a different way, all Monads are instances of Applicative, where <*> is Control.Monad.ap and *> is >>. Applicative is weaker because it does not guarantee the >>= operation. Thus Applicative captures computations that do not examine previous results and branch on values. In retrospect much monadic code is actually applicative, and with a clean rewrite this would happen.
Extending monads, with recent Constraint kinds in GHC 7.4.1 there can now be nicer designs for restricted monads. And there are also people looking at parameterized monads, and of course I include a link to something by Oleg.
In libraries these structures give rise to different type of computations.
For example Applicatives can be used to implement static effects. With that I mean effects, which are defined at forehand. For example when implementing a state machine, rejecting or accepting an input state. They can't be used to manipulate their internal structure in terms of their input.
The type says it all:
<*> :: f (a -> b) -> f a -> f b
It is easy to reason, the structure of f cannot be depend om the input of a. Because a cannot reach f on the type level.
Monads can be used for dynamic effects. This also can be reasoned from the type signature:
>>= :: m a -> (a -> m b) -> m b
How can you see this? Because a is on the same "level" as m. Mathematically it is a two stage process. Bind is a composition of two function: fmap and join. First we use fmap together with the monadic action to create a new structure embedded in the old one:
fmap :: (a -> b) -> m a -> m b
f :: (a -> m b)
m :: m a
fmap f :: m a -> m (m b)
fmap f m :: m (m b)
Fmap can create a new structure, based on the input value. Then we collapse the structure with join, thus we are able to manipulate the structure from within the monadic computation in a way that depends on the input:
join :: m (m a) -> m a
join (fmap f m) :: m b
Many monads are easier to implement with join:
(>>=) = join . fmap
This is possible with monads:
addCounter :: Int -> m Int ()
But not with applicatives, but applicatives (and any monad) can do things like:
addOne :: m Int ()
Arrows give more control over the input and the output types, but for me they really feel similar to applicatives. Maybe I am wrong about that.

Resources