【问题标题】:Please clarify the behavior of Reader Monad type请澄清 Reader Monad 类型的行为
【发布时间】:2016-08-30 15:46:16
【问题描述】:

我对 Haskell 比较陌生。现在我正在尝试更全面地理解 Reader Monad。它的目的和用途似乎更清楚了。但是在 Haskell 中查看:t reader 函数的类型时,我看到了reader :: MonadReader r m => (r -> a) -> m a。这种类型约束是什么意思? 当我尝试构建阅读器时,例如

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 =&gt; (r -&gt; a) -&gt; m a 的定义中暗示我应该将其定义为Reader Int Int

(在 Maybe 的情况下,例如 let m5 = return 5 :: Maybe Int 对我来说似乎很清楚,可能是因为 Maybe 有一个类型参数,我不确定)

【问题讨论】:

  • 上下文是什么?我可以在 GHCi 提示符下写 let myR = (\x -&gt; x + 10)myR :: (Num a, MonadReader a m) =&gt; m amyR 5 计算结果为 15。

标签: haskell monads


【解决方案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,可以在程序的其他部分进行注释,最终需要告诉类型检查器您想要哪个 MonadReader

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-10
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 2018-03-26
    • 2020-05-21
    • 2017-02-18
    相关资源
    最近更新 更多