学习惯用 Haskell 的资源(eta 缩减、符号中缀运算符、库等)[关闭]

Posted

技术标签:

【中文标题】学习惯用 Haskell 的资源(eta 缩减、符号中缀运算符、库等)[关闭]【英文标题】:Resources for learning idiomatic Haskell (eta reduction, symbolic infix operators, libraries etc.) [closed] 【发布时间】:2012-01-01 15:06:13 【问题描述】:

尽管有一些使用 Lisp 和 ML 的经验,但我在学习阅读和(惯用地)编写 Haskell 时遇到了很多麻烦,因为本地风格似乎是

尽可能消除 eta 避免使用括号以支持利用运算符优先级 将一半的逻辑打包到大量重载的非字母数字中缀运算符中

最后一个特别困难,因为有很多预定义的运算符,每个都有自己的约定和一般语义,以至于经常阅读 Haskell 变成了在 Hoogle 和 :type 中的练习。

是否有任何好的教程假定 CS/函数概念的知识,而不是专注于 Haskell 特定的习语?我正在寻找类似 Real-World Haskell 的东西,它从一个非常幼稚、明确的程序开始,然后逐渐将其转变为一种更惯用的风格,同时介绍和解释这些惯用语。但它不会介绍和解释像 monad 和类型类这样的一般概念,而是会介绍特定的 monad 和特定的类型类,例如“但这正是 Alternative monoid 所做的!”

【问题讨论】:

我认为学习如何从字面上“阅读”haskell对于学习如何阅读haskell的意义有很大帮助:***.com/questions/7746894/… 顺便说一句,您可能需要查看concatenative languages,例如Factor,以及pointfree Haskell 包,以了解您以无点风格编写的能力和愿望. Stanford lecture notes 和 ezyang page 很有帮助 【参考方案1】:

阅读 Hoogle 和/或 Haskell-2010 Language Report 找到的库文档,应该很容易掌握 ShowEqOrd 等基本类型类。

Haskell 中的数字塔似乎很复杂(根据报告,Int 类型是 11 种类型类的一个实例),但它只是为了支持数学家为我们发明的所有有用类型的数字和数字表示:例如Integer 是任意大小的整数,Int 是通常的机器字大小的整数,整数的惰性 Peano 表示(不在标准库中)被证明在图算法的实现中很有用。最重要的数字类型类是NumIntegral。您可以使用fromIntegral 函数在不同的整数类型之间进行转换。另请注意,诸如 123 之类的数字具有 Num a => a 类型,并且存在特殊的类型默认机制,旨在减少对类型声明的需求以指定您需要的确切数字类型。在高级用例中,这对您不利,因此您可能需要更改默认值。

同样的情况出现在不同类型的字符串上:没有一个单一的表示可以适合所有,所以其中有很多是在野外:StringData.ByteStringData.Text 是最重要的。

关于更复杂的类型类,最好的来源是Typeclassopedia。

对于某些类型的类,例如MonadApplicativeArrow,有很多专门的教程和研究工作。根据您的数学技能,您可能还想阅读关于类型类背后的范畴论概念的原始研究论文,例如 Eugenio Moggi 的优秀“计算和单子概念”。

至于“eta 减少”,它被称为Point-Free Style。您可以从中获取一些信息 该链接中提到的参考资料。您还可以查看 John Backus Can programming be liberated from von neumann style? 和 APL 编程语言在 1978 年发表的论文 Combinatory Logic,以更深入地了解无点风格的历史观点。

还有一些关于 Haskell 的通用书籍,例如“A Gentle Introduction to Haskell”和“Learn You a Haskell for Great Good”。

至于运算符优先级 - 您必须记住的运算符非常少:(.)($)(>>=) 的使用比其他任何东西都多(当然除了算术,但算术运算符并不令人惊讶)。

元组和列表的语法对我来说似乎也没有问题。这只是多余的:foo : bar : [][foo, bar] 相同,(,) foo bar(foo, bar) 相同。很少使用诸如(,,,,) 等更高元组的前缀版本。

另请参阅 http://www.haskell.org/haskellwiki/Section_of_an_infix_operator 以了解构造,例如 (+ 2)(2 +) 称为部分。

您还可以从 HLint 工具建议的更改中学习以改进您的代码。 HLint 可执行文件可以通过cabal install HLint 安装。

至于高级主题,我可以推荐学习纯函数式数据结构(让您设计高效的不可变数据结构并推理时间消耗),按需调用 lambda 演算(让您推理评估的内容和顺序), System Fc 类型系统(为您提供有关 haskell 类型检查器如何工作的一些背景知识)、指称语义(关于非终止、部分性和递归的推理,以及对严格性、纯度和可组合性概念的一些见解)。

【讨论】:

+1 用于 HLint,这是一个很棒的工具。 好帖子!一个错字,你的意思是:foo : bar : [][foo, bar] 相同 +1 用于 Typeclassopedia。 monadic 和 applicative 组合器的疯狂符号导致了很多新手的困惑,但是一旦您对这些感到满意(并且 typeclassopedia 是让它们感到满意的好方法),那么惯用的 Haskell 就开始变得更有意义了。【参考方案2】:

我认为"Write Yourself a Scheme in 48 Hours" 教程正是您想要的。本教程解释了如何在 Haskell 中实现 Scheme 解释器;这是一份真正让我觉得一切都很顺利的文件。

它有各种 Haskell 习语和想法的具体示例,所有这些都在一个很酷的项目中结合在一起。这对于有 Lisp 经验的人特别有用,特别是如果您已经阅读过 SICP 之类的内容或之前已经实现过 Scheme 解释器。无论哪种方式,本教程都很棒,但是如果您以前做过类似的事情,可能会更容易理解。

【讨论】:

以上是关于学习惯用 Haskell 的资源(eta 缩减、符号中缀运算符、库等)[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Haskell中的Eta减少

惯用高效的 Haskell 追加?

惯用的 Haskell 中如何实现动态规划算法?

用于简化递归的惯用 Haskell 代码

查看 Haskell 中的缩减步骤

惯用列表构造