我可以理解如何创建和思考SKI和BCKW演算,但我无法找到实际用途。也许我看得不够深?也就是说,我想知道(仅举一个例子,我并不是暗示这是真的)Java Servlets广泛使用S而Python生成器是BCW的一个例子,我只是无法透过树林看到它?
答案 0 :(得分:11)
在Haskell中,他们是everywhere!
<$>
flip
pure
id
<*>
join
从Haskell的角度来看,<$>
的意思是“在上下文中做”。
(+2) <$> (*3)
表示在乘以三后添加两个。(+2) <$> [1,2,3]
表示将列表中的每个元素添加到。(+2) <$> (read . getLine)
表示将我刚刚阅读的数字添加两个。(+2) <$> someParser
表示将我刚解析的数字添加两个。具有上下文的内容称为仿函数。所有的Java / Python / C ++迭代器都只是奇怪的内外版本的仿函数。
另一种联系:S和K组合在一起是Turing-complete。在Haskell中,pure
和<*>
一起构成了一个应用函子。
当然,了解其他组合器如何适应将需要学习Haskell。但是这个例子说明了组合者如何在语言中如此根深蒂固。
答案 1 :(得分:3)
虽然lambda和SKI演算不能反映大多数编程语言的输入和输出系统(例如图形,网络连接,甚至标准输入和输出),但实际的计算机编程方式与Lambda(和因此,SKI和BCKW),例如递归的想法和某种程度上调用函数的方式。很多这些编程语言都有lambda抽象用作函数。
答案 2 :(得分:3)
SKI和BCKW结石与Lambda演算(在函数式编程概念中具有众所周知的应用)不同,因为它们位于point-free form。另见tacit programming。它们构成了理解如何构建没有命名参数的函数程序的基础。
我们会在某些语言中看到它的应用(例如Joy和Cat)。我曾经posted on Lambda-the-Ultimate.org关于SK演算与Cat和Joy的关系。
它的价值:BCKW和SKI(或SK)的结石几乎相同,但BCKW的基础已经不再流行。
答案 3 :(得分:2)
一切都与控制有关。
也许从较低的水平开始。应用系统只是一个可以将对象应用于其他对象的系统。应用系统的一个简单示例是bash。 ls |更多 有人可能会认为他们处于某种环境中,并且上述方法对环境有所作为,然后做更多。在应用符号中这是 更多@(ls @ environment) 但是,人们可以做更复杂的事情 ls | grep模式|更多 所以现在用的是应用符号 更多@((grep @ pattern)@(ls @ environment))。 注意grep @ pattern。 Grep应用于一个模式,它返回程序以匹配ls结果中的模式。这是一个应用点,将程序应用于参数,从&#34; atomic&#34;中构建新程序。 (又名内置)程序。但是,我们不能仅使用原始应用程序或内置函数进行太多编程。我们需要一种方法来构建输入和原语的应用到我们的输入。
这就是lambda的用武之地。使用lambda可以概括 (grep @ pattern) 要将grep应用于任何输入, (grep @ X) 但是,我们必须有办法获得grep的输入。因此我们通常使用函数。 f(X)= grep @ X 上述过程称为抽象出论证。但是没有理由认为名称f是特殊的,所以我们有一个语法: lambda X. grep @ X. 然后lambda X. grep @ X可以应用于输入,输入将被替换为正文并进行评估。但是,替换可能会变得混乱,绑定变量在机器上实现会很麻烦。 S-K-I(或B,C,K,W)提供了一种无需替换即可完成lambda内容的方法,而只是交换应用程序。
总结一下,申请就是它的全部内容。在将程序应用于某事物(可能是另一个程序)的水平上推理是非常方便的。 Lambda演算提供了一种将程序的输入和应用结构化为参数的方法。 SKI提供了一种方法来做lambda而无需明确替换。
应该注意到SKI减少本质上是懒惰的,因此可能需要在现实世界中使用SKI来构建应用程序。实际上,这些论点现在可能已经得到了充分的评估,也可能是部分应用。人们可以用类型理论解决这个问题,并且如果程序处于应用程序的头部位置,则只评估其输入的程序。即,如果一个人用封闭的lambda术语写作,翻译成SKI, 然后如果 p @ arg1 @ .... 应该是这样的情况:如果p是原始程序,那么重写已经完成,因此它的所有参数都是1)可用,2)完全评估。但是,我还没有证明这一点,而且对于一个足够强大的类型理论来说可能并非如此......