我将教授离散结构的低年级课程。我之所以选择教科书《离散结构、逻辑和可计算性》,部分原因是它包含有助于使用函数式编程语言实现的示例和概念。(我也认为这是一本很好的教科书。)
我想要一种易于理解的 FP 语言来说明 DS 概念并且学生可以使用。大多数学生最多只有一两个学期的 Java 编程。在查看了 Scheme、Erlang、Haskell、Ocaml 和 SML 之后,我选择了 Haskell 或 Standard ML。出于以下概述的原因,我倾向于 Haskell,但我希望那些在其中一个或另一个中活跃的程序员的意见。
- Haskell 和 SML 都具有模式匹配,这使得描述递归算法变得轻而易举。
- Haskell 有很好的列表推导,可以很好地匹配这些列表的数学表达方式。
- Haskell 有惰性求值。非常适合使用列表理解技术构建无限列表。
- SML 有一个真正的交互式解释器,可以在其中定义和使用函数。在 Haskell 中,函数必须在单独的文件中定义并在用于交互式 shell 之前进行编译。
- SML 以易于理解的语法明确确认函数参数和返回类型。例如:val foo = fn : int * int -> int。Haskell 的隐式 curry 语法有点迟钝,但并不完全陌生。例如:foo :: Int -> Int -> Int。
- Haskell 默认使用任意精度的整数。它是 SML/NJ 中的一个外部库。SML/NJ 默认将输出截断为 70 个字符。
- Haskell 的 lambda 语法很微妙——它使用单个反斜杠。SML 更明确。不过,不确定我们是否会在这个类中需要 lambda。
本质上,SML 和 Haskell 大致等价。我倾向于 Haskell,因为我喜欢 Haskell 中的列表推导和无限列表。但我担心 Haskell 紧凑语法中大量的符号可能会给学生带来问题。根据我在 SO 上阅读其他帖子所收集到的信息,不建议从 FP 开始的初学者使用 Haskell。但我们不会构建成熟的应用程序,只是尝试简单的算法。
你怎么看?
编辑:在阅读了您的一些出色回复后,我应该澄清一些要点。
在 SML 中,在解释器中定义函数和在外部文件中定义函数之间没有语法上的区别。假设您要编写阶乘函数。在 Haskell 中,您可以将此定义放入文件中并将其加载到 GHCi 中:
fac 0 = 1
fac n = n * fac (n-1)
对我来说,这很清楚、简洁,并且符合书中的数学定义。但是如果你想直接在 GHCi 中编写函数,你必须使用不同的语法:
let fac 0 = 1; fac n = n * fac (n-1)
当使用交互式解释器时,从教学的角度来看,当学生可以在文件和命令行中使用相同的代码时,非常非常方便。
“显式确认函数”是指在定义函数时,SML 会立即告诉您函数的名称、参数的类型和返回类型。在 Haskell 中,你必须使用:type
命令,然后你会得到有点令人困惑的咖喱符号。
Haskell 还有一件很酷的事情——这是一个有效的函数定义:
fac 0 = 1
fac (n+1) = (n+1) * fac n
同样,这符合他们可能在教科书中找到的定义。在 SML 中不能这样做!