2016-08-30 76 views
1

我对Haskell相对较新。现在我试图更全面地了解Reader Monad。它的目的和用法似乎更清楚。但在Haskell查看:t reader函数的类型时,我看到了reader :: MonadReader r m => (r -> a) -> m a。这种类型约束是什么意思? 当我试图建构阅读器,如请澄清Reader Monad类型的行为

let myR = reader (\x -> x + 10) 

我看到错误

<interactive>:21:11: 
No instance for (MonadReader a0 m0) arising from a use of `reader' 
The type variables `m0', `a0' are ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Note: there are several potential instances: 
    instance MonadReader r' m => 
      MonadReader r' (Control.Monad.Trans.Cont.ContT r m) 
    -- Defined in `Control.Monad.Reader.Class' 
    instance MonadReader r ((->) r) 
    -- Defined in `Control.Monad.Reader.Class' 
    instance (Control.Monad.Trans.Error.Error e, MonadReader r m) => 
      MonadReader r (Control.Monad.Trans.Error.ErrorT e m) 
    -- Defined in `Control.Monad.Reader.Class' 
    ...plus 10 others 
In the expression: reader (\ x -> x + 10) 
In an equation for `myR': myR = reader (\ x -> x + 10) 

<interactive>:21:27: 
No instance for (Num a0) arising from a use of `+' 
The type variable `a0' is ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Note: there are several potential instances: 
    instance Num Double -- Defined in `GHC.Float' 
    instance Num Float -- Defined in `GHC.Float' 
    instance Integral a => Num (GHC.Real.Ratio a) 
    -- Defined in `GHC.Real' 
    ...plus three others 
In the expression: x + 10 
In the first argument of `reader', namely `(\ x -> x + 10)' 
In the expression: reader (\ x -> x + 10) 

很显然,我要补充的类型签名:

let myR = reader (\x -> x + 10) :: Reader Int Int 

这工作,但我怎么会从读者reader :: MonadReader r m => (r -> a) -> m a的这个定义暗示我应该将其定义为Reader Int Int

(在可能的情况下,例如,let m5 = return 5 :: Maybe Int它似乎是明确的对我来说,可能是因为也许有一种类型的参数,我不知道)

+0

什么是上下文?我可以在GHCi提示符处写'let myR =(\ x - > x + 10)',其中myR ::(数字a,MonadReader a m)=> m a','myR 5'的计算结果为15。 – chepner

回答

1

虽然它能够为默认的Int哈斯克尔没有按” t默认为MonadReader

let myR = reader (\x -> x + 10) :: Num a, MonadReader a m => m a 

大致类型检查发现的,那么它适用于Num违约规则Int并获取。

let myR = reader (\x -> x + 10) :: MonadReader Int m => m Int 

但是它没有对MonadReader定义的默认所以必须在这点返回不明确的错误。

虽然没有丢失,但如果不想注释myR,您可以注释该程序的某些其他部分,类型检查器最终需要知道您需要哪个MonadReader