0

我正在阅读为什么函数式编程很重要,作者使用 foldr 和函数组合实现了几个应用程序。我在 F# 中做了其中的一些,例如 map 函数:

let cons a lst = a::lst
let map f lst = List.foldBack (f>>cons) lst []

然后我想实现列表过滤功能,结果卡住了:

let filter pred lst = List.foldBack (what-goes-here?) lst []

这里有什么?函数应该将列表项、累积过滤列表作为输入,如果谓词返回 false,则返回相同的列表,如果返回 true,则返回 cons:ed 列表。

我想我需要这里的选项类型,但不知道如何将它们粘合在一起。是否可以使用 pred 和 cons(可能还有其他一些原语)来组合一个函数来实现这一点,而无需编写一个自定义的 lambda 函数来完成所有的工作?这是计算表达式的情况吗?

4

2 回答 2

3

对您的问题的务实答案是:

whatGoesHere = fun x xs -> if f x then x :: xs else xs

匿名函数、if-then-else 和列表都被 F# 从业者视为原语。这是编写此代码的最清晰、最可维护的方式。

唉,您还没有接受前一个响应者的等效正确答案,并且您坚持要查看不涉及 lambda 表达式的代码。不客气:

``s``s`ks``s`k`s`ks``s``s`ks``s`k`s`ks``s`k`s`kk``s
`k`s`k``s``s`ks``s`k`s`ks``s`k`s`kk``s``s`ks``s`kki
`ki`k`ki``s``s`ks``s`kki`ki
`k``s``s`ks``s`kk``s`k``s``s`ks``s`kk``s`ks``s`k`s`ks
``s`k`s`kk``s`k`si``s`kki`k``s``s`ks
``s`k`s`ks``s`k`s`kk``s``s`ks``s`kki`ki
`k`kii`ki`k`ki

以上是whatGoesHere在 SKI 组合器演算中使用布尔值和列表的合适表示,以 Unlambda 表示法打印。

为方便起见,这里是从无类型 lambda 演算到 SKI 组合子的示例编译器,以及与您的问题相对应的 lambda 演算术语的 F# 定义:

http://gist.github.com/3277850

虽然组合逻辑和 lambda 演算的等价性使得 lambda 表达式在理论上是不必要的,但它们对于表达你作为程序员的意图是必不可少的。“为什么函数式编程很重要”绝不提倡避免 lambda 表达式和辅助函数。相反——定义函数(包括高阶函数)的能力是函数式编程的核心。函数是由组合定义还是明确使用 lambda 演算几乎无关紧要:两者都是论文所讨论的“粘合剂”。

我建议你再读一遍这篇论文(也许还有它的优秀参考资料),然后安装 Haskell 或 Clean。鉴于作者提倡纯惰性默认评估模型,F# 不是探索这些想法的好平台。

于 2012-08-06T19:56:27.297 回答
0
let consT pred a lst = if pred a then a::lst else lst
let filter pred lst = List.foldBack (consT pred) lst []
于 2012-08-04T14:33:08.523 回答