# Difference between revisions of "Incompatibilities between MTL 1 and MTL 2"

Tomjaguarpaw (talk | contribs) (Deleting page that hasn't been updated for over 10 years) |
m (Reverted edits by Tomjaguarpaw (talk) to last revision by YitzGale) |
||

Line 1: | Line 1: | ||

+ | 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 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]] |

## Latest revision as of 15:19, 6 February 2021

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 with `Reader`

):

- Instances of
`Applicative`

and`Alternative`

have been added as appropriate, e.g.

```
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.

`Functor`

instances for monad transformers no longer require`Monad`

where`Functor`

is sufficient. Unfortunately this is incompatible because`Functor`

is not a superclass of`Monad`

, e.g.

```
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
`Identity`

, e.g.

```
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 both `Reader r`

and `ReaderT r`

and ensuring that they are consistent.

- The instance
`Error String`

is restructured to avoid a type synonym instance:

```
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.