1 概要
Haskell 是函數式(一切通過函數調用來完成)、靜態、隱式類型(類型由編譯器檢測,類型聲明不是必需的)、惰性(除非必要,否則什麼也不做)的語言。其最大衆化的近親大概是 ML 族語言(不過不是惰性的)。
最流行(common)的 Haskell 編譯器是 GHC,下載地址。GHC 在 GNU/Linux, FreeBSD, MacOS, Windows 以及 Solaris 平臺上都有可供使用的二進制包。安裝 GHC,即獲得 ghc 和 ghci。前者用於將 Haskell 程序庫或應用程序編譯成二進制碼。後者爲解釋器,可在編寫 Haskell 代碼後立即得到反饋.
2 表達式
大部份數學表達式都可以輸入 ghci 直接解答。Prelude> 是 GHCi 默認提示符。
Prelude>15Prelude>
15Prelude>
16字符串需要雙引號引用,以
"Hello"Prelude>
"Hello, Haskell"
調用函數時,參數緊接函數即可,其間無須添加括號。
Prelude>6Prelude>
6Prelude>
7Prelude>
1.4142135623730951Prelude>
TruePrelude>
7
3 控制檯
調用 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 之後首個非空白字符,如上例(注意:切勿使用製表符。從技術上講,八格製表符可以正常工作,但不是個好主意。也不要使用非等寬字體——顯然,有些人在編程的時候會犯此糊塗!)
4 類型
到目前爲止,我們一直沒有提到過類型聲明。那是因爲 Haskell 暗中推斷,不必聲明之。如果非要聲明類型,可用5Prelude>
5.0
類型 types(以及類型類 type classes,稍後提及)總是以大寫開頭。變量(variables)總是以小寫開頭。這是語言規則,而不只是命名習慣。
你也可以讓 ghci 告訴你選擇的內容的類型,這種方法很有用,因爲類型聲明並不是必需的。
Prelude> :t有關數字的例子則更加有趣:
Prelude> :t這些類型用到了 "類型類(type classes)" 含義如下:
- 可作爲任意數字(numeric)類型。(這就是爲什麼我既可以把42聲明爲5類型,也可以聲明爲Int類型的原因。)Double
- 可作爲任意分數(fractional)類型,但不能是整數(integral)類型。42.0
- (此爲函數調用) 可作爲任意整數(integral)類型,但不能是分數類型。gcd 15 20
在Haskell "Prelude"(你不需要import任何東西就能使用的那部分庫)中有五種數字(numeric)類型:
- 是一個至少30位(bit)精度的整數。Int
- 是一個無限精度的整數。Integer
- 是一個單精度浮點數。Float
- 是一個雙精度浮點數。Double
- 是一個沒有舍入誤差的分數/小數類型。Rational
總的一塊來看一下,
Prelude>7Prelude>
<interactive>:1:0: No instance for (Integral Double)最後值得一提的類型是
5 有結構的數據
基本數據類型可以很容易的通過兩種方式組合在一起:通過 [方括號] 組合的列表(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>詳見如何使用列表
6 函數定義
我們已經定義了一個名爲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)
7 語法規則
查看語法以瞭解更多有用的語法。
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"
8 Using libraries
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:
- Useful data structures
- Concurrent and parallel programming
- Graphics and GUI libraries
- Networking, POSIX, and other system-level stuff
- Two test frameworks, QuickCheck and HUnit
- Regular expressions and predictive parsers
- More...
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.
9 Topics that don't fit in 10 minute limit
- Advanced data types
- Arithmetic lists
- List comprehensions
- Type synonyms
- data vs newtype (and here)
- Type classes and instances
- Advanced syntax
- Advanced functions
- Monads
- File I/O
- Reading files
- Writing Files
語言: English 簡體中文