Дебашиш Гош написал хороший пост на эту тему.Основываясь на коде в этом посте:
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))
Редактировать:
У вас есть две функции List[A] => B
и List[A] => C
, и вы хотите функцию List[A] => (B, C)
.Вот для чего &&&
.Это не будет сливать петли, хотя.Я не могу себе представить, как можно соединить петли для такого случая.
Fwiw, код:
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)
Редактировать 2:
Если у вас есть функции A => B
и A => C
, вы можете объединить их в A => (B, C)
, используя &&&
.Теперь, если B : Monoid
и C : Monoid
, вы можете использовать foldMap
, чтобы получить List[A] => (B, C)
.Это сделает все за один цикл.
Код:
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))
Окончательное редактирование: (клянусь, я не редактирую это снова.)
Поскольку эти концепции берут свое начало в Хаскеле, я подумал, что было бы неплохо повторно опубликовать этот вопрос под тегом Хаскелл , и я это сделал. Ответ там , кажется, согласуется с тем, что я сказал в этой теме.Надеюсь, это помогает.