It is a well known fact that (>>=)
can be implemented using fmap
and join
while join
can be implemented using >>=
. Is there any reason we don't define the Monad
class with join
included and using the following default definitions?
join x = x >>= id
x >>= f = join $ f <$> x
This would allow a minimal definition to include either just (>>=)
or join
, instead of forcing (>>=)
. Might be a bit helpful considering category theory tends to favour join
.
The usual argument against modifying classes is that we break backwards compatibility. However, in this case, that wouldn't happen - we only add the possibility of defining Monad
using join
.
What is a Monad? A monad is an algebraic structure in category theory, and in Haskell it is used to describe computations as sequences of steps, and to handle side effects such as state and IO. Monads are abstract, and they have many useful concrete instances. Monads provide a way to structure a program.
bind and return are analogous to the corresponding functions of the same name. In fact, int * string , bind , and return form a monad.
List is also a monad. We have seen that the Maybe type constructor is a monad for building computations which may fail to return a value. You may be surprised to know that another common Haskell type constructor, [] (for building lists), is also a monad.
Monads are simply a way to wrapping things and provide methods to do operations on the wrapped stuff without unwrapping it. For example, you can create a type to wrap another one, in Haskell: data Wrapped a = Wrap a. To wrap stuff we define return :: a -> Wrapped a return x = Wrap x.
We’ve been talking a lot about what typeclasses mean and their relationship with type; a class is something that many types have in common. There are many types that support this bind operation; if a type does, then it belongs to the Monad class. You’ll sometimes hear us speak of something as being “ in a monad”.
One reason we often hesitate to include Monad in beginner content is that there are a lot of people on the internet who do not really appear to be altogether interested in learning Haskell but really want to know what a monad is, and it feels like monads have taken on a sort of outsized mythical status.
This means that every m that belongs Monad class must also belong to the Applicative class. Like Functor, the kind signature is (* -> *) – So, Monad and Functor are classes for the same kindedness of things: type constructors that have exactly one type parameter.
For List to be a monad, it must have join defined that list<list<list>>.join ().join () and list<list<list>>.map (join).join () yields the same result. This law is the one who corresponds to Monoid’s associativity. Hope this picture gives you better view at it. \mu μ as monoid operator conforms to monoid’s associativity.
That was meant to happen with the Applicative-Monad proposal (which has made it to GHC 7.10). However, there is a technical issue involving type roles in GHC which has postponed indefinitely the implementation of what you suggest.
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