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 ^
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.718281828459045
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, ....]
可以用列举符号 .. 表示一系列的列表元素, 也可以根据前面的元素步长,自动填充后面省略的元素, 但是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]
当然你可以用[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]]
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"
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 => a
6. 行计数程序 (WC.hs)
1 main = interact wordCount 2 where wordCount input = show (length (lines input)) ++ "\n"
然后新建一个quux.txt文件进行测试(内容随便写写)。
打开shell命令行切换到当前目录, 执行: runghc WC < quux.txt
即可得到txt文件的行数。