Incompatibilities between MTL 1 and MTL 2
From HaskellWiki
(Difference between revisions)
(Introductory paragraph) |
(Added content from the Haskell Platform trac wiki) |
||
| Line 3: | Line 3: | ||
See "[[Upgrading from MTL 1 to MTL 2]]" for instructions on how | See "[[Upgrading from MTL 1 to MTL 2]]" for instructions on how | ||
to make code written for version 1 work with version 2. | to make code written for version 1 work with version 2. | ||
| + | |||
| + | The interface of mtl-2 is close to that of mtl-1, but with the following differences (illustrated with <hask>Reader</hask>): | ||
| + | * Instances of <hask>Applicative</hask> and <hask>Alternative</hask> have been added as appropriate, e.g. | ||
| + | <haskell> | ||
| + | instance (Applicative m) => Applicative (ReaderT r m) where ... | ||
| + | instance (Alternative m) => Alternative (ReaderT r m) where ... | ||
| + | </haskell> | ||
| + | |||
| + | ''Rationale:'' These classes postdate the MTL, and such instances have been repeatedly defined in various packages. They belong together with the type constructors. | ||
| + | * <hask>Functor</hask> instances for monad transformers no longer require <hask>Monad</hask> where <hask>Functor</hask> is sufficient. Unfortunately this is incompatible because <hask>Functor</hask> is not a superclass of <hask>Monad</hask>, e.g. | ||
| + | <haskell> | ||
| + | instance (Monad m) => Functor (ReaderT r m) where ... | ||
| + | </haskell> | ||
| + | :is replaced by | ||
| + | <haskell> | ||
| + | instance (Functor m) => Functor (ReaderT r m) where ... | ||
| + | </haskell> | ||
| + | |||
| + | ''Rationale:'' These instances are more general, and are consistent with the instances of other classes. | ||
| + | * Simple monads are now aliases for monad trasformers applied to <hask>Identity</hask>, e.g. | ||
| + | <haskell> | ||
| + | newtype Reader r a = Reader { runReader :: r -> a } | ||
| + | </haskell> | ||
| + | :is replaced by | ||
| + | <haskell> | ||
| + | type Reader r = ReaderT r Identity | ||
| + | |||
| + | reader :: (r -> a) -> Reader r a | ||
| + | reader f = ReaderT (Identity . f) | ||
| + | |||
| + | runReader :: Reader r a -> r -> a | ||
| + | runReader m = runIdentity . runReaderT m | ||
| + | </haskell> | ||
| + | ''Rationale:'' This avoids repetition in the interfaces of both | ||
| + | [http://hackage.haskell.org/package/transformers transformers] | ||
| + | and mtl-2. It makes transformers more useful on its own, and also saves clients of mtl from defining instances for both <hask>Reader r</hask> and <hask>ReaderT r</hask> and ensuring that they are consistent. | ||
| + | * The instance <hask>Error String</hask> is restructured to avoid a type synonym instance: | ||
| + | <haskell> | ||
| + | instance Error String where | ||
| + | noMsg = "" | ||
| + | strMsg = id | ||
| + | </haskell> | ||
| + | is replaced by | ||
| + | <haskell> | ||
| + | instance ErrorList a => Error [a] where | ||
| + | strMsg = listMsg | ||
| + | |||
| + | class ErrorList a where | ||
| + | listMsg :: String -> [a] | ||
| + | |||
| + | instance ErrorList Char where | ||
| + | listMsg = id | ||
| + | </haskell> | ||
| + | ''Rationale:'' This makes the instance Haskell 98, so it can be included in the | ||
| + | [http://hackage.haskell.org/package/transformers transformers] | ||
| + | package. | ||
[[Category:Monad]] | [[Category:Monad]] | ||
Current revision
Version 2 of the Monad Transformer Library introduced some small incompatibilities relative to version 1, described below. See "Upgrading from MTL 1 to MTL 2" for instructions on how to make code written for version 1 work with version 2.
The interface of mtl-2 is close to that of mtl-1, but with the following differences (illustrated withReader
- Instances of andApplicativehave been added as appropriate, e.g.Alternative
instance (Applicative m) => Applicative (ReaderT r m) where ... instance (Alternative m) => Alternative (ReaderT r m) where ...
Rationale: These classes postdate the MTL, and such instances have been repeatedly defined in various packages. They belong together with the type constructors.
- instances for monad transformers no longer requireFunctorwhereMonadis sufficient. Unfortunately this is incompatible becauseFunctoris not a superclass ofFunctor, e.g.Monad
instance (Monad m) => Functor (ReaderT r m) where ...
- is replaced by
instance (Functor m) => Functor (ReaderT r m) where ...
Rationale: These instances are more general, and are consistent with the instances of other classes.
- Simple monads are now aliases for monad trasformers applied to , e.g.Identity
newtype Reader r a = Reader { runReader :: r -> a }
- is replaced by
type Reader r = ReaderT r Identity reader :: (r -> a) -> Reader r a reader f = ReaderT (Identity . f) runReader :: Reader r a -> r -> a runReader m = runIdentity . runReaderT m
Rationale: This avoids repetition in the interfaces of both transformers
and mtl-2. It makes transformers more useful on its own, and also saves clients of mtl from defining instances for bothReader r
ReaderT r
- The instance is restructured to avoid a type synonym instance:Error String
instance Error String where noMsg = "" strMsg = id
is replaced by
instance ErrorList a => Error [a] where strMsg = listMsg class ErrorList a where listMsg :: String -> [a] instance ErrorList Char where listMsg = id
Rationale: This makes the instance Haskell 98, so it can be included in the transformers package.
