Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why runXXX is not part of MonadTrans definition?

The MonadTrans document says:

Each monad transformer also comes with an operation runXXX to unwrap the transformer, exposing a computation of the inner monad.

So I wonder why MonadTrans is not defined as

class MonadTrans t where
  type p :: *
  type r :: * -> *
  lift:: Monad m => m a -> t m a
  run :: t m a -> p -> m (r a)

to eliminate the above clause? Is that the above definition not generic enough? If so, which monad transformer does not fit for this definition?

UPDATE

Adjusted a little bit to enable different result type.

like image 960
Earth Engine Avatar asked Dec 06 '22 01:12

Earth Engine


1 Answers

There is no universal interface for running monad transformers. For example, try running LogicT or ContT or FreeT using your interface.

Even if you could generalize your interface to handle all of these example, you would still be missing the key ingredient: laws. Type class methods should obey equations that allow you to reason about code that uses the type class interface without consulting the source of specific instances. For example, the lift method from MonadTrans must obey these to laws:

lift (return x) = return x

lift (m >>= f) = lift m >>= \x -> lift (f x)

There are nice theoretical reasons why lift should obey these laws, which become more apparent if you write the laws in this point-free style:

(lift .) return = return                        -- fmap id = id

(lift .) (f >=> g) = (lift .) f >=> (lift .) g  -- fmap (f . g) = fmap f . fmap g

In other words, (lift .) is a functor between two kleisli categories and lift is therefore a monad morphism.

A lot of thought goes into defining type classes like Functor, Monad, and MonadTrans, and the Typeclassopedia is a great place to start learning more about this topic.

like image 125
Gabriella Gonzalez Avatar answered Dec 09 '22 15:12

Gabriella Gonzalez