gpt4 book ai didi

scala - 在scala中堆叠Monad Transformers

转载 作者:行者123 更新时间:2023-12-04 12:52:31 25 4
gpt4 key购买 nike

我正在尝试堆叠 scalaz 的单子(monad)转换器以一种haskell方式:

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[_] 的单子(monad)实例”(MonadReader 和 MonadState 都扩展了 Monad[F[_])。这是一个正确的猜测吗?

如何克服这一点?

最佳答案

这不是一个真正的答案,但可能会有所帮助。

我觉得你是对的;似乎编译器无法统一 F[_]两个参数的类型(我猜是因为它是具有多个可能实例的高级类型,而不是具体类型实例)到 monad 类型。编译适用于单独的参数列表,因为类型统一仅发生在参数列表中。可以进一步说明如下:

def statyReader[F[_]](implicit r: MonadReader[F, Int], s: MonadState[F, Int]): F[Int] =
statyReader2(r, s)

def statyReader2[F[_]:Monad](r: MonadReader[F, Int], s: MonadState[F, Int]): F[Int] =
for {
counter <- s.get
secret <- r.ask
_ <- s.put(counter + secret)
} yield counter

Error: ambiguous implicit values: both
value s of type scalaz.MonadState[F,Int] and
value r of type scalaz.MonadReader[F,Int]
match expected type scalaz.Monad[F]

显然,作为一种解决方法,您可以使用两个参数列表来选择要使用的 monad:

def statyReader[F[_]](implicit r: MonadReader[F, Int], s: MonadState[F, Int]): F[Int] =
statyReader2(r)(s)

def statyReader2[F[_]](r: MonadReader[F, Int])(implicit s: MonadState[F, Int]): F[Int] =
for {
counter <- s.get
secret <- r.ask
_ <- s.put(counter + secret)
} yield counter

关于scala - 在scala中堆叠Monad Transformers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38509236/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com