Functional Programming in Scala将Applicative#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))(_ :+ _))
将unit
和map2
定义为:
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]
,但函数参数f
对A
和B
类型进行操作。在Scala解决方案中,B
通过List[B]
运算符添加到::
。
是吗?
答案 0 :(得分:1)
您对正在发生的事情的理解是正确的。但请注意,您的实现将按照预期的相反顺序生成一个列表,因此如果您将标识monad用作F
,则会返回一个反向列表,而不是相同的列表。< / p>