Sto cercando di capire come utilizzare StateT
per combinare due trasformatori di stato State
in base a un commento sulla mia risposta Scalaz state monad examples.scalaz Elenco [StateT] .sequence - impossibile trovare il valore implicito per il parametro n: scalaz.Applicativo
Sembra che sia molto vicino ma ho riscontrato un problema durante il tentativo di applicare 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)
}
così ho ottenuto fino ad avere un StateT[StateMap, Random, Int]
che posso scartare con mappa iniziali stati casuali e vuoti:
val (freq, sum) = diceAndFreqSum ! new Random(1L) apply Map[Int,Int]()
// freq: Map[Int,Int] = Map(9 -> 1)
// sum: Int = 9
Ora vorrei generare un elenco di quelli StateT
e utilizzare sequence
in modo che io possa chiamare list.sequence ! new Random(1L) apply Map[Int,Int]()
. Ma quando provo questo ottengo:
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]
^
Qualche idea? Posso usare un po 'di aiuto per l'ultimo tratto - assumendo che sia possibile.
Non capisco proprio perché non usi Scala's Random. –
@ DanielC.Sobral, Scala ha una classe Random ?! Oh sì, funzionerebbe altrettanto bene. Non è materiale per la mia domanda, quindi lascerò 'java.util.Random'. – huynhjl