scalaz List[StateT].sequence - 找不到参数 n 的隐式值:scalaz.Applicative

发布于 2024-12-10 10:45:31 字数 1533 浏览 0 评论 0原文

我试图根据我的 Scalaz 状态 monad 示例 答案。

看来我已经非常接近了,但在尝试应用sequence时遇到了问题。

import scalaz._
import Scalaz._
import java.util.Random

val die = state[Random, Int](r => (r, r.nextInt(6) + 1))

val twoDice = for (d1 <- die; d2 <- die) yield (d1, d2)

def freqSum(dice: (Int, Int)) = state[Map[Int,Int], Int]{ freq =>
  val s = dice._1 + dice._2
  val tuple = s -> (freq.getOrElse(s, 0) + 1)
  (freq + tuple, s)
}

type StateMap[x] = State[Map[Int,Int], x]

val diceAndFreqSum = stateT[StateMap, Random, Int]{ random =>
  val (newRandom, dice) = twoDice apply random
  for (sum <- freqSum(dice)) yield (newRandom, sum)
}

所以我得到了一个 StateT[StateMap, Random, Int] ,我可以用初始随机和空地图状态来解包:

val (freq, sum) = diceAndFreqSum ! new Random(1L) apply Map[Int,Int]()
// freq: Map[Int,Int] = Map(9 -> 1)
// sum: Int = 9

现在我想生成这些 StateT 的列表 并使用 sequence 以便我可以调用 list.sequence ! new Random(1L) 应用 Map[Int,Int]()。但当我尝试这个时,我得到:

type StT[x] = StateT[StateMap, Random, x]
val data: List[StT[Int]] = List.fill(10)(diceAndFreqSum)
data.sequence[StT, Int]

//error: could not find implicit value for parameter n: scalaz.Applicative[StT]
          data.sequence[StT, Int]
                       ^

有什么想法吗?我可以在最后一段时间内使用一些帮助 - 假设这是可能的。

I'm trying to figure out how to use StateT to combine two State state transformers based on a comment on my Scalaz state monad examples answer.

It seems I'm very close but I got an issue when trying to apply sequence.

import scalaz._
import Scalaz._
import java.util.Random

val die = state[Random, Int](r => (r, r.nextInt(6) + 1))

val twoDice = for (d1 <- die; d2 <- die) yield (d1, d2)

def freqSum(dice: (Int, Int)) = state[Map[Int,Int], Int]{ freq =>
  val s = dice._1 + dice._2
  val tuple = s -> (freq.getOrElse(s, 0) + 1)
  (freq + tuple, s)
}

type StateMap[x] = State[Map[Int,Int], x]

val diceAndFreqSum = stateT[StateMap, Random, Int]{ random =>
  val (newRandom, dice) = twoDice apply random
  for (sum <- freqSum(dice)) yield (newRandom, sum)
}

So I got as far as having a StateT[StateMap, Random, Int] that I can unwrap with initial random and empty map states:

val (freq, sum) = diceAndFreqSum ! new Random(1L) apply Map[Int,Int]()
// freq: Map[Int,Int] = Map(9 -> 1)
// sum: Int = 9

Now I'd like to generate a list of those StateT and use sequence so that I can call list.sequence ! new Random(1L) apply Map[Int,Int](). But when trying this I get:

type StT[x] = StateT[StateMap, Random, x]
val data: List[StT[Int]] = List.fill(10)(diceAndFreqSum)
data.sequence[StT, Int]

//error: could not find implicit value for parameter n: scalaz.Applicative[StT]
          data.sequence[StT, Int]
                       ^

Any idea? I can use some help for the last stretch - assuming it's possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对你再特殊 2024-12-17 10:45:31

啊看看 scalaz Monad 源,我注意到有一个隐式 def StateTMonad这确认了 StateT[M, A, x] 是类型参数 x 的 monad。此外,单子也是应用程序,通过查看 Monad的定义特性并通过插入 REPL:

scala> implicitly[Monad[StT] <:< Applicative[StT]]
res1: <:<[scalaz.Monad[StT],scalaz.Applicative[StT]] = <function1>

scala> implicitly[Monad[StT]]
res2: scalaz.Monad[StT] = scalaz.MonadLow$anon$1@1cce278

所以这给了我定义一个隐式 Applicative[StT] 来帮助编译器的想法:

type StT[x] = StateT[StateMap, Random, x]
implicit val applicativeStT: Applicative[StT] = implicitly[Monad[StT]]

这成功了:

val data: List[StT[Int]] = List.fill(10)(diceAndFreqSum)
val (frequencies, sums) =
  data.sequence[StT, Int] ! new Random(1L) apply Map[Int,Int]()

// frequencies: Map[Int,Int] = Map(10 -> 1, 6 -> 3, 9 -> 1, 7 -> 1, 8 -> 2, 4 -> 2)
// sums: List[Int] = List(9, 6, 8, 8, 10, 4, 6, 6, 4, 7)

Ah looking at the scalaz Monad source, I noticed there was an implicit def StateTMonad that confirms that StateT[M, A, x] is a monad for type parameter x. Also monads are applicatives, which was confirmed by looking at the definition of the Monad trait and by poking in the REPL:

scala> implicitly[Monad[StT] <:< Applicative[StT]]
res1: <:<[scalaz.Monad[StT],scalaz.Applicative[StT]] = <function1>

scala> implicitly[Monad[StT]]
res2: scalaz.Monad[StT] = scalaz.MonadLow$anon$1@1cce278

So this gave me the idea of defining an implicit Applicative[StT] to help the compiler:

type StT[x] = StateT[StateMap, Random, x]
implicit val applicativeStT: Applicative[StT] = implicitly[Monad[StT]]

That did the trick:

val data: List[StT[Int]] = List.fill(10)(diceAndFreqSum)
val (frequencies, sums) =
  data.sequence[StT, Int] ! new Random(1L) apply Map[Int,Int]()

// frequencies: Map[Int,Int] = Map(10 -> 1, 6 -> 3, 9 -> 1, 7 -> 1, 8 -> 2, 4 -> 2)
// sums: List[Int] = List(9, 6, 8, 8, 10, 4, 6, 6, 4, 7)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文