What is the Haskells Readers' Monad used for?

Good examples of Not a Functor / Functor / Applicative / Monad?

I want to suggest a more systematic approach to answering this question and also show examples that don't use special tricks like "bottom" values ​​or infinite data types or the like.

When do type constructors not have type class instances?

In general, a type constructor cannot have an instance of a particular type class for two reasons:

  1. The type signatures of the required methods from the type class cannot be implemented.
  2. Can implement the type signatures but fail to meet required laws.

Examples of the first kind are simpler than those of the second kind, since for the first kind we only have to check whether a function can be implemented with a certain type signature, while for the second kind we have to prove that no implementation could possibly be the laws to satisfy.

Specific examples

  • A type constructor that cannot have a function instance because the type cannot be implemented:

This is a contrafunctor, not a functor, as the type parameter is used in a contravariant position. It is impossible to implement a function with the type signature.

  • A type constructor that is not a legitimate functor although the type signature can be implemented by:

The strange aspect of this example is that we can of the correct type, although it cannot possibly be a functor because it is in a contravariant position. So the implementation of 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 functional laws are not met (this requires some simple calculations to check).

In fact there is only a professor - it is neither a functor nor a counterfuntor.

  • A legal functor that does not apply because the type signature cannot be implemented by: Take the writer monad and remove the condition that it should be a monoid. It is then impossible to construct a value of type Off.

  • An inapplicable functor because the type signature cannot be implemented by:.

  • A functor that cannot be legally used although the type class methods can be implemented:

The type constructor is a functor because it is only used in covariant positions.

The only possible implementation of the type signature of is is a function that always returns:

However, this implementation does not meet the identity law for applicable functors.

  • A functor that is, but not one because the type signature of cannot be implemented.

I don't know of such examples!

  • A functor that is but not because laws cannot be met, although the type signature of can be implemented.

This example has sparked some discussion, so it is safe to say that it is not easy to prove this example to be correct. However, several people have independently verified this using different methods. For more information, see Is `data PoE a = Empty | Pair a a` a Monad? .

It is a bit of a hassle to prove that there is no lawful authority. The reason for the non-monadic behavior is that there is no natural way to implement when a function could return for different values ​​from or for.

It is perhaps clearer to look at what is also not a monad and try to implement for it. You will find that there is no intuitively sensible way to implement.

In the cases indicated by it seems to be clear that we cannot generate from six different values ​​of the type in a reasonable and symmetrical way. We could certainly choose any subset of these six values ​​- for example always take the first non-empty one - but this would not satisfy the laws of the monad. The return of also does not comply with the law.

  • A tree-like data structure that is not a monad is, although it is for associative, but does not fulfill the laws of identity.

The common tree-like monad (or "a tree with functore-shaped branches") is defined as

This is a free monad over the functor. The form of the data is a tree with each branch point being a "plethora" of subtrees. The standard binary tree would also be preserved.

If we change this data structure by also making the leaves in the shape of the functor, we get what I call "semimonad" - it has that satisfies the laws of nature and associativity, but its method fails one of the laws of identity. "Semi-lemonades are half-groups in the category of endofectors, what is the problem?" This is the type class.

For simplicity, I'll define the method instead of:

Branch transplant is standard, but leaf transplant is not standard and produces one. This is not a problem for the associativity law, but breaks one of the identity laws.

When do polynomial types have monad instances?

None of the functors and can be assigned a valid instance, although obviously it is.

These functors have no tricks - no or no tricky laziness / rigor, no infinite structures, and no type class restrictions. The instance is completely standard. The functions and can be implemented for these functors, but do not comply with the laws of the monad. In other words, these functors are not monads because of the lack of a certain structure (however, it is not easy to understand what exactly is missing). For example, a small change in the functor can result in a monad: Is a monad. Another similar functor is also a monad.

Constructions for polynomial monads

In general, there are some constructions here that generate feasible s from polynomial types. In all of these constructions there is a monad:

  1. where is any monoid
  2. where is a monad and a monoid
  3. where and are arbitrary monads
  4. where is any monad

The first construction is, the second construction is. The third construction is a component-related product of monads: is defined as the component-related product of and, and is defined by omitting cross-product data (e.g. is mapped to by omitting the second part of the tuple):

The fourth construction is defined as

I have verified that all four constructions produce rightful monads.

I guess that there are no other constructions for polynomial monads. For example, the functor is not obtained by any of these constructions and is therefore not monadic. is monadic, however, since it is isomorphic to the product of three monads, and is. It is also monadic because it is isomorphic to the product of and.

The four constructions shown above allow us to get any sum of any number of products of any number of, for example and so on. All such type constructors have (at least one) instance.

It remains to be seen, of course, what use cases could exist for such monads. Another problem is that the instances derived from constructions 1-4 are generally ambiguous. For example, an instance can be assigned to the type constructor in two ways: by construction 4 using the monad, and by construction 3 using the type isomorphism. Again, finding use cases for these implementations is not immediately obvious.

The question remains - for any polynomial data type, how to recognize whether there is an instance. I don't know how to prove that there are no other constructions for polynomial monads. I don't think there is any theory yet to answer this question.