In Eric Torreborre\'s blogpost on the paper Essence of the Iterator Pattern, he describes how the cartesian product of a traverse is also a traverse.
Can anyone show me
Debasish Ghosh has written a nice post on this topic. Based on the code in that 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 a function List[A] => (B, C)
. That's what &&&
is for. This won't fuse the loops though. I cannot imagine how it can be possible to fuse 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] =
accum: List[Int] => Int =
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 functions A => B
and A => C
you can merge them into A => (B, C)
using &&&
. Now if B : Monoid
and C : Monoid
, you can use foldMap
to get List[A] => (B, C)
. This will do the stuff in one loop.
Code:
scala> val f: Int => Int = identity
f: Int => Int =
scala> val g: Int => List[String] = i => List(i.toString + "Z")
g: Int => List[String] =
scala> List(1, 2, 3, 4).foldMap(f &&& g)
res95: (Int, List[String]) = (10,List(1Z, 2Z, 3Z, 4Z))
Final edit: (I swear I am not editing this again.)
Since these concepts have their origins in Haskell, I thought it'd be a good idea to re-post this question under Haskell tag, and I did. The answer there seems to be consistent with whatever I have said in this thread. Hôpe this helps.