如何遍历scalaz

时间:2014-10-01 04:57:48

标签: scala scalaz

我试图简化实际代码但不是很多。

考虑到以下输入,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

2 个答案:

答案 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