1. 初識解釋器ghci 1.1 查看幫助: :? 1.2 修改提示符: :set prompt ghci>>> 1.3 加自己指定模塊: :module + Data.Ratio 2. 基本交互 2.1 基本算術運算 中綴表達式: 首碼表達式: 2.2 算術中的負數 -8其實並不是直接表示負數8, ...
1. 初識解釋器ghci
1.1 查看幫助: :?
1.2 修改提示符: :set prompt ghci>>>
1.3 加自己指定模塊: :module + Data.Ratio
2. 基本交互
2.1 基本算術運算
中綴表達式:
1 ghci>>> 3 ^ 3 2 27 3 ghci>>> 2 + 4 4 6 5 ghci>>> 5 / 3 6 1.6666666666666667
首碼表達式:
1 ghci>>> (^) 3 3 2 27 3 ghci>>> (/) 5 2 4 2.5 5 ghci>>> (+) 1 9
2.2 算術中的負數
1 ghci>>> -8 2 -8 3 ghci>>> 1 + -4 4 5 <interactive>:57:1: 6 Precedence parsing error 7 cannot mix ‘+’ [infixl 6] and prefix `-' [infixl 6] in the same infix expression 8 ghci>>> 1 + (-3) 9 -2
-8其實並不是直接表示負數8, 而是利用一元操作符'-'對8取負, 所以第3行不能與中綴表達式一起使用, 除非加上()。
1 ghci>>> 55*-2 2 3 <interactive>:60:3: 4 Not in scope: ‘*-’ 5 Perhaps you meant one of these: 6 ‘*>’ (imported from Prelude), ‘**’ (imported from Prelude), 7 ‘*’ (imported from Prelude)
這樣是另一種不認識的操作符。
2.3 布爾運算(True False)和比較運算
3種運算符: && || not Haskell中True不是1, False不是0.
1 ghci>>> True && False 2 False 3 ghci>>> True || False 4 True 5 ghci>>> not False 6 True 7 ghci>>> True && 1 8 9 <interactive>:75:9: 10 No instance for (Num Bool) arising from the literal ‘1’ 11 In the second argument of ‘(&&)’, namely ‘1’ 12 In the expression: True && 1 13 In an equation for ‘it’: it = True && 1 14 ghci>>> 1 == 1 15 True 16 ghci>>> 4 > 6 17 False 18 ghci>>> 33 <= 50 19 True
2.4 運算符優先順序和結合性
可以有命令 :info 查看指定操作符的優先順序值, 1表示最低, 9 表示最高。
1 ghci>>> 2 + 3 * 5 ^ 2 2 77 3 ghci>>> :info (+) 4 class Num a where 5 (+) :: a -> a -> a 6 ... 7 -- Defined in ‘GHC.Num’ 8 infixl 6 + 9 ghci>>> :info (*) 10 class Num a where 11 ... 12 (*) :: a -> a -> a 13 ... 14 -- Defined in ‘GHC.Num’ 15 infixl 7 * 16 ghci>>> :info (^) 17 (^) :: (Num a, Integral b) => a -> b -> a -- Defined in ‘GHC.Real’ 18 infixr 8 ^View Code
2.5 變數的定義
使用ghci的let定義臨時變數
1 ghci>>> pi 2 3.141592653589793 3 ghci>>> e 4 5 <interactive>:84:1: Not in scope: ‘e’ 6 ghci>>> let e = exp 1 7 ghci>>> e 8 2.718281828459045View Code
exp 1 表示調用指數函數exp,參數為1, 不必使用()。
3. 列表(List)
列表長度可以是任意的。
空的列表就是[]。
列表中的元素必須相同類型。
1 ghci>>> [1,2,3,4] 2 [1,2,3,4] 3 ghci>>> [] 4 [] 5 ghci>>> ['foo','rt'] 6 7 <interactive>:89:2: 8 Syntax error on 'foo' 9 Perhaps you intended to use TemplateHaskell 10 In the Template Haskell quotation 'foo' 11 ghci>>> ["foo","rt"] 12 ["foo","rt"] 13 ghci>>> [True,False,1,"str"] 14 15 <interactive>:91:15: 16 Couldn't match expected type ‘Bool’ with actual type ‘[Char]’ 17 In the expression: "str" 18 In the expression: [True, False, 1, "str"] 19 In an equation for ‘it’: it = [True, False, 1, ....]View Code
可以用列舉符號 .. 表示一系列的列表元素, 也可以根據前面的元素步長,自動填充後面省略的元素, 但是float類型可能會涉及到四捨五入的情況:
1 ghci>>> [1..10] 2 [1,2,3,4,5,6,7,8,9,10] 3 ghci>>> [1,4,7..20] 4 5 <interactive>:93:7: parse error on input ‘..’ 6 ghci>>> [1,4,7,..20] 7 8 <interactive>:94:8: parse error on input ‘..’ 9 ghci>>> [1,4..20] 10 [1,4,7,10,13,16,19] 11 ghci>>> [1,8..20] 12 [1,8,15] 13 ghci>>> [1.2..2.3] 14 [1.2,2.2] 15 ghci>>> [1.2..2.6] 16 [1.2,2.2] 17 ghci>>> [1.2..3.6] 18 [1.2,2.2,3.2] 19 ghci>>> [1.0..1.8] 20 [1.0,2.0]View Code
當然你可以用[1..], 省略終點的方式產生一個無窮數列。
3.1 列表操作符 (連接)
使用 ++ 連接N個相同元素的列表。
使用 : 在某列表頭部加入。(格式必須: 前面是單個元素,後面是一個列表)
1 ghci>>> [] ++ [False,True] ++ [False] 2 [False,True,False] 3 ghci>>> 100:[2,3,4,5] ++ [6,8,4] 4 [100,2,3,4,5,6,8,4] 5 ghci>>> [2,3]:1 6 7 <interactive>:105:1: 8 Non type-variable argument in the constraint: Num [[t]] 9 (Use FlexibleContexts to permit this) 10 When checking that ‘it’ has the inferred type 11 it :: forall t. (Num t, Num [[t]]) => [[t]]View Code
4. 字元串和字元
字元串就是很多個單字元組成的列表, 所以可以列表的連接操作。
putStrLn 是輸出字元串的函數。 \n \r 與C語言一樣轉意。
""與[]是相同的。
1 ghci>>> "Hello Haskell" 2 "Hello Haskell" 3 ghci>>> putStrLn "We are in ghci console.\n See here." 4 We are in ghci console. 5 See here. 6 ghci>>> 'c' 7 'c' 8 ghci>>> let a = ['h','e','l','l','o'] 9 ghci>>> a 10 "hello" 11 ghci>>> a == "hello" 12 True 13 ghci>>> [] == "" 14 True 15 ghci>>> 'w':"Haskell" 16 "wHaskell" 17 ghci>>> "Frist" ++ "Second" 18 "FristSecond"View Code
5. 類型表示
Haskell中,所有的類型以大寫字母開始,變數以小寫字母開始。
可以使用 :set +t 是ghci返回結果的類型, :unset +t。
可以使用 :type var/expression 顯示變數或表達式的類型, 並不參與計算。
1 ghci>>> :set +t 2 ghci>>> 'c' 3 'c' 4 it :: Char 5 ghci>>> "foo" 6 "foo" 7 it :: [Char] 8 ghci>>> 7^80 9 40536215597144386832065866109016673800875222251012083746192454448001 10 it :: Num a => a 11 ghci>>> :m +Data.Ratio 12 ghci>>> 11 % 33 13 1 % 3 14 it :: Integral a => Ratio a 15 ghci>>> 11 % 3.3 16 17 <interactive>:121:1: 18 No instance for (Fractional a0) arising from a use of ‘it’ 19 The type variable ‘a0’ is ambiguous 20 Note: there are several potential instances: 21 instance Integral a => Fractional (Ratio a) 22 -- Defined in ‘GHC.Real’ 23 instance Fractional Double -- Defined in ‘GHC.Float’ 24 instance Fractional Float -- Defined in ‘GHC.Float’ 25 In the first argument of ‘print’, namely ‘it’ 26 In a stmt of an interactive GHCi command: print it 27 ghci>>> :unset +t 28 ghci>>> type 'c' 29 30 <interactive>:123:6: parse error on input ‘'’ 31 ghci>>> :type 'c' 32 'c' :: Char 33 ghci>>> :type 1+8 34 1+8 :: Num a => aView Code
6. 行計數程式 (WC.hs)
1 main = interact wordCount 2 where wordCount input = show (length (lines input)) ++ "\n"
然後新建一個quux.txt文件進行測試(內容隨便寫寫)。
打開shell命令行切換到當前目錄, 執行: runghc WC < quux.txt
即可得到txt文件的行數。