Debashish Ghosh wrote a good post on this topic. Based on the code in this post:
scala> List(1, 2, 3, 4) res87: List[Int] = List(1, 2, 3, 4) scala> .traverse[({ type L[X] = State[Int, X] })#L, String] { cur => | state { (acc: Int) => (acc + cur, cur.toString + "Z") } | } res88: scalaz.State[Int,List[String]] = scalaz.States$$anon$1@199245 scala> .apply(0) res89: (Int, List[String]) = (10,List(1Z, 2Z, 3Z, 4Z))
Edit:
You have two functions List[A] => B
and List[A] => C
, and you want to use the function List[A] => (B, C)
. Why &&&
. However, this will not work. I can’t imagine how to use loops for such a case.
Fwiw, code:
scala> val shape = (_ : List[Int]) map (_.toString + "Z") val accum = (_ : List[Int]).sum shape: List[Int] => List[java.lang.String] = <function1> accum: List[Int] => Int = <function1> scala> val xs = List(1, 2, 3, 4) xs: List[Int] = List(1, 2, 3, 4) scala> (shape &&& accum) apply xs res91: (List[java.lang.String], Int) = (List(1Z, 2Z, 3Z, 4Z),10)
Edit 2:
If you have the functions A => B
and A => C
, you can combine them into A => (B, C)
with &&&
. Now, if B : Monoid
and C : Monoid
, you can use foldMap
to get List[A] => (B, C)
. This will make the material in one cycle.
the code:
scala> val f: Int => Int = identity f: Int => Int = <function1> scala> val g: Int => List[String] = i => List(i.toString + "Z") g: Int => List[String] = <function1> scala> List(1, 2, 3, 4).foldMap(f &&& g) res95: (Int, List[String]) = (10,List(1Z, 2Z, 3Z, 4Z))
Final editing: (I swear I am not editing it again.)
Since these concepts originate in Haskell, I thought it would be a good idea to republish this question in the Haskell tag, and I did. The answer there seems to be consistent with what I said in this thread. Hôpe it helps.