haskell - 用于学习惯用 Haskell 的资源(eta 缩减、符号中缀运算符、库等)

标签 haskell idioms

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

  • 尽可能进行 eta 消除
  • 避开括号,有利于利用运算符优先级
  • 将一半的逻辑打包到大量重载的非字母数字中缀运算符中

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

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

最佳答案

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

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

同样的情况也适用于不同类型的字符串:没有一种单一的表示形式适合所有情况,因此其中许多都是野生的:StringData.ByteStringData.Text 是最重要的。

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

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

至于“eta 减少”,它被称为 Point-Free Style 。您可以从以下位置获取一些信息 该链接中提到的引用文献。您还可以查看组合逻辑(John Backus Can programming be liberated from von neumann style? 于 1978 年发表的论文)和 APL 编程语言,以获得有关无点风格的更丰富的历史视角。

还有关于 Haskell 的一般书籍,例如“Haskell 简介”和“为伟大的利益而学习 Haskell”。

至于运算符优先级 - 您必须记住的运算符确实很少:(.)($)(>>=) 比其他所有东西都使用得更多(当然算术除外,但算术运算符并不令人惊讶)。

元组和列表的语法对我来说似乎也没有问题。它只是多余的: 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 类型检查器如何工作的一些背景知识)、指称语义(关于非终止、偏爱和递归的推理,以及对严格性、纯粹性和可组合性概念的一些见解)。

关于haskell - 用于学习惯用 Haskell 的资源(eta 缩减、符号中缀运算符、库等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8189405/

相关文章:

haskell - 将 Lens' a b 转换为 Lens' a(也许是 b)

string - 在haskell中删除文本文件中的重复项

haskell - 列表类型签名

r - R : map, 中的列表理解不是过滤器

haskell - 在 Haskell 中展开左 Binder

haskell - 迭代列表,直到结果列表为空列表

idioms - API 设计 : is "fault tolerance" a good thing?

python - 将这个简单的 block 转换为惯用的 Python 代码

clojure - 在 Clojure 中转换生长向量的惯用方法

c++ - 如何调用使用数组将函数应用于可变参数包的成语