实现Applicative#traverse

时间:2013-12-10 03:17:02

标签: scala

Functional Programming in ScalaApplicative#traverse定义为:

def traverse[A,B](as: List[A])(f: A => F[B]): F[List[B]]
    as.foldRight(unit(List[B]()))((a, fbs) => map2(f(a), fbs)(_ :: _))

但是,我将此功能实现为:

  def traverse[A,B](as: List[A])(f: A => F[B]): F[List[B]] =
    as.foldRight(unit(List[B]()))((elem, acc) => map2(acc, f(elem))(_ :+ _))

unitmap2定义为:

  def map2[A,B,C](fa: F[A], fb: F[B])(f: (A,B) => C): F[C]
  def unit[A](a: => A): F[A]

据我了解我的实施情况,map2(acc, f(elem))(_ :+ _))的行为如下:

  

为每个(元素,累加器),调用map2(acc,f(elem)(_:+ _))   将f(elem)的结果(类型F [B])附加到累加器(类型F [List [B]])

对于我的实施,然后,在(f: (A,B) => C)traverse来电的map2部分,List[B]B添加到自身。

map2接受参数F[A]F[B],但函数参数fAB类型进行操作。在Scala解决方案中,B通过List[B]运算符添加到::

是吗?

1 个答案:

答案 0 :(得分:1)

您对正在发生的事情的理解是正确的。但请注意,您的实现将按照预期的相反顺序生成一个列表,因此如果您将标识monad用作F,则会返回一个反向列表,而不是相同的列表。< / p>