与面向堆栈的语言相比,Haskell语法需要相对较嘈杂的f . g $ 3
而不是3 g f
。这个选择的主要设计参数是什么?为什么选择函数应用程序作为默认的Haskell运算符,而不是组合?
回答
这也可以写成f (g 3)
。
为什么哈斯克尔不是拼接的语言?
基于A History of Haskell,它是由多种函数式编程和懒惰的语言实验,包括ML的影响。作为第4节,语法描述:
钻营
继传统可以追溯到弗雷格的两个参数的函数可以表示为一个说法,自己返回一个参数的函数的函数。摩西Scḧonfinkel和哈斯克尔咖喱磨练了这个传统,并被称为咖喱。功能应用程序由并列表示并关联到左侧。因此,
f x y
被解析(f x) y
。这导致简洁和强大的代码。例如,要将每个数字排列在列表中,我们编写map square [1,2,3]
,同时在列表中列出我们编写的每个数字map (map square) [[1,2],[3]]
。哈斯克尔,像基于演算许多其他语言,同时支持咖喱和uncurried定义,
钻营的概念是如此重要的Haskell的语义,并在其核心的演算这种安排的任何其他方法将不良相互作用与语言。
我的猜测是演算和有用性(在现实世界的情景)。
在演算,空间应用,因此它的感觉更类似于谁知道它的人。
在最常用的语言,平常的事情做一个功能就是应用它。 Haskell不是基于堆栈的语言,因此选择是在那里完成的。
- 的面向堆栈式不那么多组成如序列功能;
3 g f
就是这样一种语言,而是在Haskell中f $ g $ 3
。当然,这相当于f . g $ 3
,但只有当您立即将合成应用于某个值时,它才会起作用。在Haskell中,你经常编写函数来将它们交给一些更高阶的combinator,或者做一个没有意义的定义。在需要某种显式模块的面向堆栈的语言中,在Haskell中只需要.
运算符。 通常,你不只是链接“原子”功能。当然,你不会处理全球命名的单字母函数,所以这个微小的
.
或$
实际上并没有明显的明显差异。并且经常地,如rmmh所说,您链部分应用功能,例如,main = interact $ unlines . take 10 . filter ((>20) . length) . lines
没有便宜的紧密绑定应用程序,这会更麻烦。此外,将单独的
.
标记为尚未立即应用但仅由其组成的内容是非常自然的。
如果你有兴趣在Haskell,胡达克,休斯,历史佩顿琼斯& Wadler的"A History of Haskell: Being Lazy with Class"是关于这一主题的最知名的纸,和良好的值得一读。
它并没有直接解决你的问题,但它确实指出了一个非常相关的事实:Haskell被创建为一个小团队现有语言之间的统一折衷。引用第2.2节(“巴别塔”):
由于所有这些活动的结果,由80年代中期出现了许多研究者,包括作家,谁是在设计非常感兴趣,并纯懒惰语言的实现技术。事实上,我们很多人都独立设计了我们自己的懒惰语言,并忙于为他们构建自己的实现。我们每个人都在写关于我们工作的文件,在我们描述我们的实现技术之前,我们首先必须描述我们的语言。那巴别这个懒塔贡献的语言包括:
- 米兰达[...]
- 懒惰ML(LML)[...]
- 奥威尔[...]
- Alfl [...]
- 标识[...]
- 清洁[...]
- 思考[...]
- 菊花[...]
所以答案可能就是Haskell从它的前辈语言中复制了它。而且,由于一些这些语言反过来是基于Lisp和ML的灵感,或者受到Lisp和ML的启发,他们可能会类似地从它们中复制它们。回复引用你的问题:
这个选择的主要设计参数是什么?
机会是,从来没有一个可持续的选择的选择。无论如何,很少有高级语言用于基于堆栈的设计,很少有人知道它们。
- 1. 为什么typeof被称为运算符而不是函数?
- 2. 为什么使用'op_Addition'作为运算符'+'而不是名称'+'?
- 3. 为什么不允许作为Haskell中缀运算符?
- 4. 为什么不是Haskell部分应用程序工作?
- 5. Haskell中函数应用程序运算符的使用
- 6. 为什么Angular默认不选择正确的选择选项?
- 7. 为什么不应该在函数中使用“=”R运算符?
- 8. 为什么不是默认
- 9. 为什么“==”运算符不起作用
- 10. 试图了解Haskell中的函数应用程序运算符
- 11. Rails:为什么不使用默认的应用程序布局?
- 12. 为什么在选择方法中使用OR运算符而不是AND运算符?
- 13. 为什么Postgres Hstore索引适用于? (运算符)而不是EXIST(函数)?
- 14. 为什么空函数组合在Haskell中工作?
- 15. 为什么在C中的printf函数不是模运算符?
- 16. 为什么++运算符将整数增加4而不是1?
- 17. 默认的默认构造函数,为什么不是用户提供的默认构造函数?
- 18. '='运算符的默认操作是什么?
- 19. Haskell美元运算符应用程序
- 20. 使用选择值作为运算符
- 21. 选择/选项元素的默认“搜索”行为是什么?
- 22. 为什么选择0,...,而不是SELECT
- 23. 为什么Ruby使用=〜而不是〜=来匹配运算符?
- 24. 为什么使用new运算符而不是std :: vector?
- 25. 为什么不应用默认样式?
- 26. 为什么我的程序打印默认构造函数?
- 27. 为什么使用AUFS作为默认的Docker存储后端而不是devicemapper?
- 28. 为什么==运算符不像char数组那样工作?
- 29. 我可以在Swift中使用运算符作为默认函数参数吗?
- 30. 为什么Angular 2不加载默认的应用程序根组件?
据我记得,甚至没有任何其他方式进行讨论。哈斯克尔的血统让他们选择显而易见。 – augustss