【发布时间】:2012-06-12 23:12:47
【问题描述】:
我知道如何使用仅使用“绑定”操作的 list monad 来执行与 Scheme(或 Python)的 map 和 filter 函数等效的操作。
这里有一些 Scala 来说明:
scala> // map
scala> List(1,2,3,4,5,6).flatMap {x => List(x * x)}
res20: List[Int] = List(1, 4, 9, 16, 25, 36)
scala> // filter
scala> List(1,2,3,4,5,6).flatMap {x => if (x % 2 == 0) List() else List(x)}
res21: List[Int] = List(1, 3, 5)
在 Haskell 中也是一样的:
Prelude> -- map
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> [x * x])
[1,4,9,16,25,36]
Prelude> -- filter
Prelude> [1, 2, 3, 4, 5, 6] >>= (\x -> if (mod x 2 == 0) then [] else [x])
[1,3,5]
Scheme 和 Python 也有一个 reduce 函数,它通常与 map 和 filter 组合在一起。 reduce 函数使用提供的二元函数组合列表的前两个元素,然后将结果组合为下一个元素,依此类推。计算值列表的总和或乘积的常见用途。这里有一些 Python 来说明:
>>> reduce(lambda x, y: x + y, [1,2,3,4,5,6])
21
>>> (((((1+2)+3)+4)+5)+6)
21
有没有办法只使用列表单子上的绑定操作来做这个reduce 的等效操作?如果 bind 不能自己执行此操作,那么执行此操作的最“单子”方式是什么?
如果可能,请在回答时限制/避免使用语法糖(即:Haskell 中的 do 符号或 Scala 中的序列推导)。
【问题讨论】:
标签: functional-programming monads