Haskell 是一种通用的纯函数编程语言。这个页面将帮助你尽快迈入 Haskell 的大门。
John Hughes 写了一篇很好的论文:Why Functional Programming Matters。
Haskell 和其它大多数语言一样,有两种执行方式:批量执行的编译方式,和交互执行的解释方式。在交互式环境下,你可以直接在命令行输入你想要计算的表达式,这是一种做实验的好方法。
GHC | 支持编译和解释方式(GHCi) | 可能是特性最全的环境 |
Hugs | 仅支持解释方式 | 不过相比 GHC 要轻巧得多 |
GHC 和 Hugs 都在 Windows 上运行。Hugs 是 windows 平台上最好的解释器。如果你想在 Mac OSX 上安装的话,请参看 这里 (flw 注:GHC 和 Hugs 在 Debian 下都有相应的包,其它 Linux 平台下想必也有。支持 RPM 的系统可以从 www.rpmfind.net 上找找看。当然也可以从官方网站上下载源码包编译安装。)
请注意,下面这个例子不能在 Hugs 下运行(截止到 20050308 为止),因为 Hugs 不支持在命令行定义函数。你必须把定义放到一个源代码文件里。
如果你学过其它编程语言的话,那你一定编过“Hello world”程序。不过在 Haskell 中,你的第一个程序不是“Hello world”,而是一个阶乘函数。
打开一个终端。如果你安装了 GHC 的话,就请输入 ghci(GHC 解释器的名字)。如果你安装的是 Hugs 的话,就请输入 hugs。
$ ghci ___ ___ _ / _ \ /\ /\/ __(_) / /_\// /_/ / / | | GHC Interactive, version 6.4, for Haskell 98. / /_\\/ __ / /___| | http://www.haskell.org/ghc/ \____/\/ /_/\____/|_| Type :? for help. Loading package base-1.0 ... linking ... done. Prelude>
在 GHCi 中,我们既可以从一个源代码文件中装载程序,也可以直接在命令提示符下定义。试试下面的这个:
Prelude> let fac n = if n == 0 then 1 else n * fac (n-1)
这样就定义了一个叫做 fac 的函数,它可以计算一个整数的阶乘(第四步中我们再来仔细讨论它)
输入 fac 12,这样可以把 12 作为参数传递给 fac 函数。
*Main> fac 12 479001600
大功告成!你现在已经成功地运行了你的第一个 Haskell 程序。
在进入长篇大论之前,先来看看 Haskell 版本的 “Hello World”:
putStrLn "Hello World"
在 GHCi 中输入上面的文字,然后你就可以得到你想要的效果。
如果你想用一个可执行文件来打印这句话的话,你可以把下面这段文字保存到 hello.hs 文件中:
module Main where main = putStrLn "Hello World"
编译器要求必须得有一个叫做 main 的函数,这样它便知道程序该从何处开始执行。用命令 ghc hello.hs -o hello 来编译它,然后运行就可以了。Unix/Linux 下用 ./hello 来运行,windows 下用 hello.exe 来运行。
函数式编程有一个显著的特点就是所有的工作都用“函数”来完成。函数是没有副作用(flw 注:side effects,也译作“边际效应”)的。它们返回一个和参数相关的值。为了进行输入输出(比如往屏幕上打印一句话),你可以想象成函数可以拥有一个名为“world”的参数,这个参数包括了所有的外部状态,然后函数返回一个修改过了的 world(比如屏幕上多了“Hello World”这几个字),而这个修改过了的 world 又可以带到随后的函数中。
Haskell 提供一些类似的东西,而且更加省事:它把函数和现实世界的相互影响,称作 IO 行为。这样当一个函数把一个数字转换成可打印字符串时,它变具有类型 Int -> String。而一个从终端上读取指定长度的字符串的函数也许会具有类型 Int -> IO String,它的意思是说,给函数一个整数,它可以返回一个“从终端上读取一个字符串”的 IO 行为。这也就是为什么 main 函数具有类型 IO 的原因——你通常希望你的程序能够和现实世界交互,那样的话就它就得是一个 IO 行为。
说起来有些拗口。但其实和其它的编程语言没有什么分别,只不过其它的语言把它们叫做“语句”和“表达式”罢了。这样的好处是 Haskell 有一个坚实的框架来处理这些事,它的名字就叫“IO Monad”。
如果你想要一个关于如何在 Haskell 中进行 IO 工作的快速介绍的话,我建议你看看 IO 介绍
有很多不错的 Haskell 教程和书籍,下面这些都是我们推荐的: