Haskell 是函数式(一切通过函数调用来完成)、静态、隐式类型(类型由编译器检测,类型声明不是必需的)、惰性(除非必要,否则什么也不做)的语言。其最大众化的近亲大概是 ML 族语言(不过不是惰性的)。
最流行(common)的 Haskell 编译器是 GHC,下载地址。GHC 在 GNU/Linux, FreeBSD, MacOS, Windows 以及 Solaris 平台上都有可供使用的二进制包。安装 GHC,即获得 ghc 和 ghci。前者用于将 Haskell 程序库或应用程序编译成二进制码。后者为解释器,可在编写 Haskell 代码后立即得到反馈.
大部份数学表达式都可以输入 ghci 直接解答。Prelude> 是 GHCi 默认提示符。
Prelude>15Prelude>
15Prelude>
16字符串需要双引号引用,以
"Hello"Prelude>
"Hello, Haskell"
调用函数时,参数紧接函数即可,其间无须添加括号。
Prelude>6Prelude>
6Prelude>
7Prelude>
1.4142135623730951Prelude>
TruePrelude>
7
调用 I/O actions 进行控制台输入和输出。如:
Prelude>Hello, HaskellPrelude>
9Prelude>
True
2 + 2 = 4Prelude>
ABCDE 12345通过
4 16
(4 是输入。16 是结果。)
main = do putStrLn "What is 2 + 2?" x <- readLn if x == 4 then putStrLn "You're right!" else putStrLn "You're wrong!"
运行 ghc --make Test.hs,得到 Test(Windows 上是 Test.exe)。顺便接触了 if 语句。
do 之后首个非空白字符,如上例(注意:切勿使用制表符。从技术上讲,八格制表符可以正常工作,但不是个好主意。也不要使用非等宽字体——显然,有些人在编程的时候会犯此糊涂!)
5Prelude>
5.0
类型 types(以及类型类 type classes,稍后提及)总是以大写开头。变量(variables)总是以小写开头。这是语言规则,而不只是命名习惯。
你也可以让 ghci 告诉你选择的内容的类型,这种方法很有用,因为类型声明并不是必需的。
Prelude> :t有关数字的例子则更加有趣:
Prelude> :t这些类型用到了 "类型类(type classes)" 含义如下:
在Haskell "Prelude"(你不需要import任何东西就能使用的那部分库)中有五种数字(numeric)类型:
总的一块来看一下,
Prelude>7Prelude>
最后值得一提的类型是:1:0: No instance for (Integral Double)
基本数据类型可以很容易的通过两种方式组合在一起:通过 [方括号] 组合的列表(lists),和通过 (圆括号) 组合的元组(tuples)。
列表可以用来储存多个相同类型的值:
Prelude>[1,2,3]Prelude>
[1,2,3,4,5]Prelude>
[1,3,5,7,9]Prelude>
[True,False,True]
Haskell 中的字符串(String)其实只不过是字符(Character)类型的 List:
Prelude>"Hello"冒号
"CHello"
元组则和列表不同,它用来储存固定个数,但类型不同的值。【译者注:列表是类型相同,但个数不固定,甚至还可以是无限个数】
Prelude>(1,True)Prelude>
[(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e')]上面这个例子用到了
类型一般都符合你的期望:
Prelude> :t列表在Haskell中被大量使用。有些函数能够很好地对列表进行运算:
Prelude>有两个作用于双元素元组的优美函数:
Prelude>详见如何使用列表
main = do putStrLn "What is 2 + 2?" x <- readLn if x == 4 then putStrLn "You're right!" else putStrLn "You're wrong!"
module Main where factorial n = if n == 0 then 1 else n * factorial (n - 1) main = do putStrLn "What is 5! ?" x <- readLn if x == factorial 5 then putStrLn "You're right!" else putStrLn "You're wrong!"
使用命令ghc --make Test.hs重新编译。并用下面的命令执行
$ ./Test What is 5! ? 120 You're right!这是一个函数。表现得就和内建函数一样,可以通过
$ ghci Test.hs << GHCi banner >> Ok, modules loaded: Main.Prelude Main> :t
factorial 0 = 1 factorial n = n * factorial (n - 1)
查看语法以了解更多有用的语法。
secsToWeeks secs = let perMinute = 60 perHour = 60 * perMinute perDay = 24 * perHour perWeek = 7 * perday in secs / perWeek
classify age = case age of 0 -> "newborn" 1 -> "infant" 2 -> "toddler" _ -> "senior citizen"
Everything used so far in this tutorial is part of the Prelude, which is the set of Haskell functions that are always there in any program.
The best road from here to becoming a very productive Haskell programmer (aside from practice!) is becoming familiar with other libraries that do the things you need. Documentation on the standard libraries is at http://haskell.org/ghc/docs/latest/html/libraries/. There are modules there with:
module Main where import qualified Data.Map as M errorsPerLine = M.fromList [ ("Chris", 472), ("Don", 100), ("Simon", -5) ] main = do putStrLn "Who are you?" name <- getLine case M.lookup name errorsPerLine of Nothing -> putStrLn "I don't know you" Just n -> do putStr "Errors per line: " print n
If you want something that's not in the standard library, try looking at http://hackage.haskell.org/packages/hackage.html or this wiki's applications and libraries page. This is a collection of many different libraries written by a lot of people for Haskell. Once you've got a library, extract it and switch into that directory and do this:
runhaskell Setup configure runhaskell Setup build runhaskell Setup install
On a UNIX system, you may need to be root for that last part.
语言: English 简体中文