According to the Haskell wikibook, a Monad
called m
is a Functor
with two additional operations:
unit :: a -> m a
join :: m (m a) -> m a
That's nice, but I have something slightly different. Glossing over the gory details, I have a type that has good unit
and join
functions, but its fmap
is not well behaved (fmap g . fmap f
is not necessarily fmap (g.f)
). Because of this, it cannot be made an instance of Monad
. Nonetheless, I'd like to give it as much generic functionality as possible.
So my question is, what category theoretic structures are similar to monads in that they have a unit
and join
?
I realize that on some level, the above question is ill-defined. For monads the unit
and join
definitions only make sense in terms of the fmap
definition. Without fmap
, you can't define any of the monad laws, so any definitions of unit
/join
would be equally "valid." So I'm looking for functions other than fmap
that it might make sense to define some "not-monad" laws on these unit
and join
functions.
Monads are not about ordering/sequencing Just as you can use monads for state, or strictness, you can use them to order computations. But there are also commutative monads, like Reader, that don't order anything. So ordering is not in any way essential to what a monad is.
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.
As I understand, every monad is a functor but not every functor is a monad. A functor takes a pure function (and a functorial value) whereas a monad takes a Kleisli arrow, i.e. a function that returns a monad (and a monadic value).
Map is not one of the defining properties of monads, however, because it's technically just a special case of FlatMap. A lifting function like Unit will wrap its object in a container, even if that object is itself the same type of container.
Well here's one law you should have with just unit
and join
. Given x :: m a
,
join (unit x) = x
To show that this didn't just come from nowhere, let's start with an existing monad law:
return x >>= f = f x
Given that m >>= f = join (fmap f m)
join (fmap f (return x)) = f x
Select f = id
join (fmap id (return x)) = id x
Use the functor law that fmap id = id
join (id (return x)) = id x
Use the obvious id a = a
join (return x) = x
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