Pregunta

I'm reading Monad Transformers Step by Step. On page 6, while introducing some subclasses of Monad, the writer gives the following code examples:

class (Monad m) => MonadError e m | m -> e where
    throwError :: e -> m a
    catchError :: m a -> (e -> m a) -> m a

class (Monad m) => MonadReader r m | m -> r where
    ask :: m r
    local :: (r -> r) -> m a -> m a

What does the | m -> e part mean?

¿Fue útil?

Solución

That's a functional dependency. It's an extension available in GHC. You can read more about them here but the basic idea they convey is that one of the types "determines" the other type. They've fallen out of favor lately since type families can convey the same information and more, but in an easier to comprehend, more functional manner.

Edit: an example, taken from a question I asked about this topic a year ago.

I had started with this code using functional dependencies:

class Shuffle a b | a -> b where
  indices    :: a -> Array Int b
  reorganize :: a -> Array Int b -> a

@ehird responded with this solution:

class Shuffle a where
  type Elt a
  indices    :: a -> Array Int (Elt a)
  reorganize :: a -> Array Int (Elt a) -> a

So what's happened is essentially that the arrow 'a -> b' which says 'a determines b' is changed into a type family with 'a' being the type variable and a type 'b' listed inside the type class.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top