2017-02-12 51 views
1

我有一个基本的类型类:Typeclass使用`=>`运算符时的混淆?

class MyClass a where 
    (-+) :: a -> a -> a 

instance MyClass Int where 
    e1 -+ e2 = e1 + e2 * 100 

myFunction :: MyClass a => a -> a -> a 
myFunction e1 e2 = e1 -+ e2 

我明白上面是如何工作的。

不过,我不明白,在这个类型类的声明中使用的=>运营商:

class Monad m => MonadReader r m | m -> r where 

是与单子类本作MonadReader类?为什么使用这个?

+1

这就是说'MonadReader r m'成立时'Monad m'必须始终保持。 'Monad m'是'MonadReader r m'的超类(尽管我不确定_superclass_这个单词是否真的可以缩放到像MonadReader这样的多参数类型类)。 – Alec

+1

在函数定义和类定义中,当m是Monad时,'Monad m =>'可以读为*“。在后一种情况下,它确实建立了Monad和MonadReader之间的关系。也就是说,每个MonadReader实例都必须是Monad实例。 IOW它使'Monad'的MonadReader r' a *子类*(如果你可以将这个概念应用于多参数类型类)。 –

回答

3

class Monad m => MonadReader r m | m -> r where 

我们

  1. 超类约束Monad m,这意味着两个给定类型rm可以由MonadReader r m情况下,如果他们不仅实现所列举的方法MonadReader的定义,也是约束条件Monad m,即mMonad类型的一个实例类。

  2. 有一个函数依赖确定rm,即用于的MonadReader r1 m1MonadReader r2 m2任何两个instance S,如果m1 ~ m2r1 ~ r2然后。