pattern matching
如果模式匹配多個值,必須用括號括起來(if you want to bind to several variables (even if one of them is just _ and doesn't actually bind at all), we have to surround them in parentheses. )
head' :: [a] -> a
head' [] = error "can head an empty list, you Dummy"
-- x:xs need to be put in parentheses
head' (x:xs) = x
模式匹配中,List直接用[x, y], [x, _]來進行匹配,不需要括號, kind of syntax sugar
tt :: (Show a) => [a] => String
tt [] = "empty list"
-- same as: tt [x] = ...
tt (x:[]) = "one element" ++ (show x)
-- same as tt [x, y] = ..
tt (x:y:[]) = "two elements" ++ (show x) ++ ", " ++ (show y)
-- can't use tt [x, y, _], may be more than 3
tt (x:y:_) = "3 or more than 3 elements"
patterns
可以在匹配的同時保留整體
>>let tall all@(x:xs) = (show all) ++ ", first = " ++ show x
>> tall "554"
"\"554\""
guards
guards
可以用來處理多個條件,類似于c的switch
max' :: (Ord a) => a -> a -> a
max' a b
| a > b = addOne a
-- otherwise 處理其他
| otherwise = b
where addOne x = (x+1)
decOne x = (x-1)
-- 也可以寫成一行
-- max' a b | a > b = a | otherwise = b
可以在guards
后面加where
定義方法,不過where
需要對齊(Notice that all the names are aligned at a single column. If we don't align them nice and proper, Haskell gets confused because then it doesn't know they're all part of the same block.)
where
跟正常方法一樣,可以用pattern matching, 也可以嵌套定義where
let
表達式
let <bindings> in <expr>
, 多行bindings需要對齊,單行可以;
隔開
>>(let a = 100; b = 200; c = 300 in a*b*c, let foo="Hey "; bar = "there!" in foo ++ bar)
(6000000,"Hey there!")
case
表達式
head' :: [a] -> a
head' [] = error "No head for empty lists!"
head' (x:_) = x
-- 跟上面效果一致,方法pattern match只是syntax sugar
head' xs = case xs of [] -> "No head for empty lists!"
(x:_) -> x
-- where 里邊也可以用第一種形式
describeList :: [a] -> String
describeList xs = "The list is " ++ what xs
where what [] = "empty."
what [x] = "a singleton list."
what xs = "a longer list."
常見錯誤
-- real world haskell
-- file: ch03/BogusPattern.hs
data Fruit = Apple | Orange
apple = "apple"
orange = "orange"
-- apple/orange只是模式匹配的變量,不是global var=> apple/orange
whichFruit :: String -> Fruit
whichFruit f = case f of
apple -> Apple
orange -> Orange
-- file: ch03/BogusPattern.hs
equational apple = Apple
equational orange = Orange
-- file: ch03/BogusPattern.hs
betterFruit f = case f of
"apple" -> Apple
"orange" -> Orange
pattern match不能多次用同一個變量表示匹配變量相同
(A name can appear only once in a set of pattern bindings)
bad_nodesAreSame (Node a _ _) (Node a _ _) = Just a