我试图简化实际代码但不是很多。
考虑到以下输入,f和g的实现仅用于示例,实际的更复杂
scala> val m = Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4)
m: scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2, c -> 3, d -> 4)
scala> val f : Int => Option[Int] = i => if (i % 2 == 0) Some(i) else None
f: Int => Option[Int] = <function1>
scala> val g = (a:Int, l:List[Int]) => a :: l
g: (Int, List[Int]) => List[Int] = <function2>
以下是流程:
m.foldLeft(List[Int]()) { case (l, (k, v)) =>
f(v) match {
case Some(w) => g(w, l)
case None => l
}
}
是否可以使用scalaz更好地揭示意图?
我想到m.traverseS
答案 0 :(得分:0)
如果g
确实需要处理整个List[Int]
,那么我立即想到Endo
(需要稍加重写g
):
val f: Int => Iterable[Int] = ???
val g: Int => Endo[List[Int]] = ???
val m = Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4)
Foldable[List].fold(m.values.toList flatMap f map g).apply(List[Int]())
我不确定那会更清楚。
答案 1 :(得分:0)
m.collect{ case(s, i) => (s, f(i))}
.filter{ case (s,i) => i.isDefined }
.toList
.traverseS({s => State({ l: List[Int] => (g(s._2.get, l), ())})})
.run(Nil)
._1
.reverse