Reputation: 533
I'm learning about monads in Haskell, I understood why they are useful, I understood in general what bind, join, return do.
I also looked at basic usage examples for the basic reader / writer / state / list / maybe monads.
Still, being a beginner, I still don't feel I have a grip on what the "run" function (e.g. runState, runReader, runWriter) mean in general. It does not seem to have a generic signature like the above functions, and I don't get it if it's definable / makes sense for all monads.
Upvotes: 9
Views: 455
Reputation: 15673
The run
function for most monads is actually just an artifact of how the monad is internally represented; For example, the Reader
monad could theoretically be represented as just
type Reader r a = r -> a
State
as
type State s a = s -> (s, a)
and so on. However, if we did that then we couldn't provide different typeclass (including Monad
) implementations for Reader
and State
as they'd both just be represented by (->)
.
-- that is, if we wrote
instance Functor (Reader r)
-- ....
and
instance Functor (State s)
-- ...
our compiler would complain we're trying to give two different Functor
implementations for (->) a
.
So instead of type
we just more or less write the same thing with newtype
, e.g.
newtype Reader r a = Reader { runReader :: r -> a }
or
newtype State s a = State { runState :: s -> (s, a)}
As you can see, the run
functions don't actually do anything here, they just "unwrap" the newtype so we can get the underlying value.
(actual implementations may involve monad transformers and therefore look a bit more complicated, but they're essentially still doing the same thing).
Upvotes: 16