我对Haskell相对较新。现在我想更全面地了解Reader Monad。它的目的和用法似乎更清晰。但是在查看:t reader
函数类型的Haskell中,我看到reader :: MonadReader r m => (r -> a) -> m a
。这种类型约束意味着什么?
当我试图构建Reader时,例如
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
?
(如果是Maybe,例如let m5 = return 5 :: Maybe Int
,我似乎很清楚,可能是因为Maybe有一个类型参数,我不确定)
答案 0 :(得分:1)
虽然可以默认Int
Haskell不会将Monad
默认为Reader
。
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
,您可以注释程序的其他部分,最终需要告知类型检查器{{1>你想要的。