【发布时间】:2016-07-21 16:10:52
【问题描述】:
我正在尝试以 Haskell 方式堆叠 scalaz 的 monad transfromers:
statyReader :: (MonadReader Int m, MonadState Int m) => m Int
斯卡拉:
def statyReader[F[_]](implicit r: MonadReader[F, Int], s: MonadState[F, Int]): F[Int] = for {
counter <- s.get
secret <- r.ask
_ <- s.put(counter + secret)
} yield counter
它编译时使用 1 隐式传递,但不是 2:
Error:(13, 18) value flatMap is not a member of type parameter F[Int]
counter <- s.get
^
Error:(14, 18) value flatMap is not a member of type parameter F[Int]
secret <- r.ask
^
Error:(15, 21) value map is not a member of type parameter F[Unit]
_ <- s.put(counter + secret)
^
为什么会这样?我的猜测是编译器现在很困惑它应该选择哪个“F[_]”的单子实例(MonadReader 和 MonadState 都扩展了Monad[F[_])。这是一个正确的猜测吗?
如何克服这个问题?
【问题讨论】:
-
次要观点:在 Haskell 中,我不会将其称为“堆叠 monad 转换器”,因为我会用它来指代例如
StateT s (ReaderT r IO) a。不过,确实,在这样的堆栈中,我们会有多个类型约束,所以它是相关的。 -
我不认为这两个隐式参数是问题,否则你会得到错误“模糊隐式值”(见github.com/scalaz/scalaz/issues/1110)。
-
@devkat 如果我只通过 1 个隐含的,事情就可以了 :)
-
对不起,我的评论是没有根据的 :) 有趣的是,当一个参数是显式的而另一个是隐式的时,它会起作用;如果两者都是显式的或隐式的,它就不起作用。
-
实际上它适用于 1 隐式并且不适用于 1 显式(例如
justReader[F[_]](r: MonadReader[F, Int])vsjustReader[F[_]](implicit r: MonadReader[F, Int])),所以我现在完全迷路了。
标签: scala haskell monads scalaz monad-transformers