如何使用原语在F#中实现列表过滤功能

时间:2012-08-03 17:04:08

标签: f# functional-programming pointfree

我正在阅读Why functional programming matters,其中作者使用foldr和函数组合实现了几个应用程序。我在F#中做了其中一些,例如地图功能:

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 []

what-goes-here?函数应该将列表项作为输入,累积的筛选列表如果谓词返回false则返回相同的列表,如果返回true则返回cons:ed列表

我想我需要这里的选项类型,但无法弄清楚如何将各种东西粘在一起。 是否有可能使用pred和cons(以及可能还有一些其他原语)来构建一个函数来实现这个而不用编写一个自定义lambda函数来完成所有的管道工作?这是计算表达式的一种情况吗?

2 个答案:

答案 0 :(得分: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

以上是使用合适的SKI组合子演算中的whatGoesHere 以Unlambda符号印刷的布尔值和列表的表示。

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

http://gist.github.com/3277850

虽然组合逻辑和lambda演算的等价 从理论上讲,lambda表达式是不必要的,它们是不可或缺的 表达你作为程序员的意图。 “为什么功能编程很重要” 绝不提倡避免使用lambda表达式和辅助函数。 相反 - 定义功能的能力,包括 高阶函数是函数式编程的核心。 功能是否由组合或定义来定义并不重要 明确使用lambda演算:两者都是“胶水” 论文谈到了。

我建议你给论文(也许是它的优秀参考文献) 另一个读取,然后安装Haskell或Clean。鉴于作者 提倡纯粹的懒惰评估模型,F#并不是一个好的 探索这些想法的平台。

答案 1 :(得分:0)

let consT pred a lst = if pred a then a::lst else lst
let filter pred lst = List.foldBack (consT pred) lst []