Sto pensando di iniziare ad usare lo stile Monadic nel mio codice Scala per, tra gli altri, lo stato di threading. Ecco un esempio semplificato di combinare 3 funzioni monadici (e la cura solo circa gli effetti collaterali)Scalaz - combinando List e State Monad in per comprensione
import scalaz._
import Scalaz._
object MonadTest {
def adder(i: Int) = State[String, Int] ({str: String => (str + i.toString + " ", i) })
val oneTwoThreeMonad = for {
m1 <- adder(1)
m2 <- adder(2)
m3 <- adder(3)
} yield m3
oneTwoThreeMonad("start: ")._1 //String = "start: 1 2 3 "
}
Tutto questo è abbastanza auto-esplicativo e funziona come previsto. Ma perché questo approccio mi sia davvero utile vorrei poterlo combinare con la comprensione per List
. Ecco un po 'di (non funzionante) il codice per mostrare quello che voglio dire:
val list = List(1, 2, 3)
val oneTwoThreeBis = for {
i <- list
mx <- adder(i)
} yield mx
Fondamentalmente vorrei essere in grado di coniugare monadi sulla base di argomentazioni da un List
- eseguire la funzione monadica su ciascuno degli elementi del list
e accumula gli effetti collaterali mentre procedo. Capisco la sintassi di esempio non funziona e vedo perché non lo fa - Sto solo cercando un equivalente pulito ed elegante.
Sono quasi sicuro che è possibile ottenere ciò utilizzando i trasformatori scalaz monad, più specificamente con StateT
ma non sono sicuro di come si farebbe per farlo.
PS. Sto usando Scalaz 7.0-M3, quindi la sintassi potrebbe essere leggermente diversa dalla più comune 6.x.
Sembra esattamente quello che sto cercando. Ma non cambia il fatto che dovrò imparare a usare i trasformatori di stato in pratica prima o poi;) – nietaki
Mi sono appena accorto di aver già letto una delle tue risposte contenente una descrizione dettagliata di 'traverse' e' traverseS' e ti ho persino elogiato per questo. Non riesco a immaginare come non sia stato con me ... – nietaki
Se qualcuno ha bisogno di fare qualcosa di simile a Cats piuttosto che a Scalaz, nota che non c'è 'traverseS' ma ho un esempio funzionante di esso usando' traverseU' qui : https://github.com/benhutchison/gesture/blob/master/core/jvm/src/test/scala/gesture/GestureProcessorSpec.scala#L34 –