2016-08-30 118 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