【问题标题】:scalaz List[StateT].sequence - could not find implicit value for parameter n: scalaz.Applicativescalaz List[StateT].sequence - 找不到参数 n 的隐式值:scalaz.Applicative
【发布时间】:2011-10-16 05:39:46
【问题描述】:

我正在尝试根据对我的Scalaz state monad examples 答案的评论,弄清楚如何使用StateT 组合两个State 状态转换器。

看来我已经很接近了,但是在尝试申请 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) apply 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]
                       ^

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

【问题讨论】:

  • 我只是不明白你为什么不使用 Scala 的 Random。
  • @DanielC.Sobral,Scala 有一个 Random 类?!哦,是的,它也可以。这对我的问题不重要,所以我会离开java.util.Random

标签: scala scalaz monad-transformers state-monad


【解决方案1】:

啊,看着scalaz Monad source,我注意到有一个implicit def StateTMonad 确认StateT[M, A, x] 是类型参数x 的monad。 monads 也是 applicatives,通过查看 the definition of the Monad trait 和在 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 2022-08-05
    • 2017-02-02
    • 2016-01-17
    • 2011-10-17
    • 2016-03-31
    • 2015-01-27
    相关资源
    最近更新 更多