为什么选择函数应用程序作为默认Haskell运算符,而不是组合?

为什么选择函数应用程序作为默认Haskell运算符,而不是组合?,haskell,Haskell,Haskell语法需要相对嘈杂的f。与面向堆栈的语言中的3gf相比,g$3。这个选择的主要设计依据是什么?我的猜测是lambda演算和实用性(在现实世界的场景中) 在lambda演算中,空间就是应用程序,因此它与了解它的人感觉更相似 在最常用的语言中,使用函数通常是应用它。Haskell不是一种基于堆栈的语言,因此在那里做出了选择。也可以编写f(g3) 为什么Haskell不是连接语言 基于,它受到各种函数编程和惰性语言实验的影响,包括ML。如第4节所述,语法描述: 咖喱 按照弗雷格的传统,两个

Haskell语法需要相对嘈杂的
f。与面向堆栈的语言中的
3gf
相比,g$3
。这个选择的主要设计依据是什么?

我的猜测是lambda演算和实用性(在现实世界的场景中)

在lambda演算中,空间就是应用程序,因此它与了解它的人感觉更相似


在最常用的语言中,使用函数通常是应用它。Haskell不是一种基于堆栈的语言,因此在那里做出了选择。

也可以编写
f(g3)

为什么Haskell不是连接语言

基于,它受到各种函数编程和惰性语言实验的影响,包括ML。如第4节所述,语法描述:

咖喱

按照弗雷格的传统,两个参数的函数可以表示为一个参数的函数,该参数本身返回一个参数的函数。这一传统是由摩西·舍恩克尔和哈斯克尔·咖喱磨练而成,后来被称为咖喱。函数应用由并置表示,并与左侧关联。因此,
fxy
被解析为
(fx)y
。这就产生了简洁而强大的代码。例如,要将列表中的每个数字平方,我们写
map square[1,2,3]
,而要将列表中的每个数字平方,我们写
map(map square)[[1,2],[3]
。Haskell和其他许多基于lambda演算的语言一样,支持curried和uncarried定义

咖喱语的概念是哈斯克尔语义学的核心,其核心是lambda演算,因此任何其他排列方法都会与该语言产生不良的交互作用

  • 面向堆栈的样式与其说是组合,不如说是序列函数
    3gf
    是这样一种语言,在Haskell中相当于
    f$g$3
    。当然,这相当于
    f。g$3
    ,但它只在您立即将合成应用于某个值时有效。在Haskell中,通常编写函数只是为了将它们交给某个高阶组合器,或是为了进行无点定义。在需要某种显式块的面向堆栈的语言中,在Haskell中,它只需要
    操作符
  • 通常,你不只是链“原子”函数。当然,您不会处理全局命名的单字母函数,因此微小的
    $
    在详细程度上并不会产生显著的差异。而且,正如rmmh所说,通常情况下,您会链接部分应用的函数,例如

    main = interact $ unlines . take 10 . filter ((>20) . length) . lines
    
    如果没有廉价的紧密绑定应用程序,这将非常麻烦。此外,很自然地使用分隔符
    来标记没有立即应用的内容,而只是合成的内容


  • 如果你对哈斯凯尔、哈达克、休斯、佩顿·琼斯和瓦德勒的历史感兴趣,那么《佩顿·琼斯和瓦德勒》是这方面最著名的论文,非常值得一读

    它并没有直接解决您的问题,但它确实指出了一个非常相关的事实:Haskell是作为小型团队的一组现有语言之间的统一折衷而创建的。引用第2.2节(“巴别塔”):

    作为所有这些活动的结果,到了20世纪80年代中期,包括作者在内的许多研究人员对纯惰性语言的设计和实现技术都非常感兴趣。事实上,我们中的许多人都独立设计了自己的惰性语言,并忙于为它们构建自己的实现。我们每个人都在写关于我们努力的论文,在论文中,我们首先必须描述我们的语言,然后才能描述我们的实现技术。促成这座懒惰的巴别塔的语言包括:

    • 米兰达[…]
    • 惰性ML(LML)[……]
    • 奥威尔[…]
    • Alfl[…]
    • Id[…]
    • 清洁[……]
    • 思考[…]
    • 黛西[…]
    因此,答案可能只是Haskell从其前身语言中复制了这一点。而且,由于这些语言中有很多是基于Lisp和ML的,或者是受Lisp和ML的启发,所以他们可能也从Lisp和ML中复制了Lisp和ML。回到你的问题上来:

    这种选择的主要设计依据是什么


    很有可能,这一选择从来没有持续的争论。无论如何,很少有高级语言支持基于堆栈的设计,也很少有人知道它们。

    据我记忆所及,甚至没有讨论过以其他方式进行设计。考虑到哈斯克尔的祖先,他们的选择是显而易见的。