Scalaz List [StateT] .sequence - could not find an implicit value for parameter n: scalaz.Applicative

I am trying to understand how to use StateT to combine two State state transformers based on comments on my examples of the Scalaz state monad .

I seem to be very close, but I had a problem 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 to StateT[StateMap, Random, Int] , which I can deploy with the initial random and empty states of the map:

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

Now I would like to generate a list of these StateT and use sequence so that I can call list.sequence ! new Random(1L) apply Map[Int,Int]() list.sequence ! new Random(1L) apply Map[Int,Int]() . But when I try 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 - if possible.

+14
scala scalaz state-monad monad-transformers
Oct 16 2018-11-11T00:
source share
1 answer

Ah, looking at the source of the scan, Monad , I noticed that there is an implicit def StateTMonad that confirms that StateT[M, A, x] is a monad for an X-type parameter. In addition, monads are applicative, as evidenced by looking at the definition of Monad and digging into 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]] 

This 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) 
+9
Oct 16 2018-11-11T00:
source share



All Articles