I am currently playing arround with the scalaz State Monad. I want to implement a processing pipeline where a dynamic number of modifications will be applied to an initial State. I want to get out a final State after all processings have been done.
Here is a better graphical example.
+-------+ +-------+ +-------+
| | | | | |
Initial State +-----> | m1 | +----> | m2 | +----> | m3 | +----> Final State
| | | | | |
+-------+ +-------+ +-------+
I came up with this code
import scalaz._
import Scalaz._
object Main2 {
def main(args: Array[String]) {
val m1 = State[String, Unit] { (x:String) =>(x + " " + x, () )}
val m2 = State[String, Unit] { (x:String) =>(x.toUpperCase(), () )}
val m3 = State[String, Unit] { (x:String) =>(x.toLowerCase(), () )}
val finalState = for(
_ <- m1;
_ <- m2;
f <- m3
) yield (f)
println( finalState.run("Foo") )
}
}
This works so far but i dont know the exact number of modiffications at compile time so i can not use a for comprehension.
What i need is this
import scalaz._
import Scalaz._
object Main2 {
def main(args: Array[String]) {
val m1 = State[String, Unit] { (x:String) =>(x + " " + x, () )}
val m2 = State[String, Unit] { (x:String) =>(x.toUpperCase(), () )}
val m3 = State[String, Unit] { (x:String) =>(x.toLowerCase(), () )}
type MyState = State[String, Unit];
val modifications = List[MyState](m1,m2,m3);
modifications.???.run("Foo")
}
}
Would this be a better signature for my modifications in terms of error handling ?
type ModificationType = StateT[Try, String, Unit]
Thanks for your help
Well, the easy way is something like
modifications.reduceLeft((a: MyState, b:MyState) => a.flatMap(_ => b));
which is essentially a rewrite of the for comprehension.
It looks like scalaz also provides sequenceU
which could also be used
modifications.sequenceU
but I'm not sure about that one. (I don't have scala compiler with me)
For your second question, yes, that should provide you with what you need.