为什么说参数argument是右结合的
例如:
add :: Int -> Int -> Int -> Int ->Int
add a1 a2 a3 a4 = a1 + a2 + a3 + a4
add 1 2 3 4 <==>1+ (add 2 3 4 )<==>1+(2+add 3 4) <==>1 +(2 + (3 + add 4)) <==>1+ (2 + (3 +4))
但它本身是从左到右运算的
导入数据库,如import Data.List
定义的变量不够用时
find :: Eq a => [a] -> a -> Int
find xs x = indexOf 0 xs x
where
indexOf :: Eq a => Int -> [a] -> a -> Int
indexOf n (y:ys) x =
| x == y = n
| otherwise = indexOf (n+1) ys x
拉姆达表达式
f x = 2*x + 1 写成 f = \x-> (2*x+1) (x是输入,->后是输出) (\前面的空格不要漏掉,表达式用括号括起来)
(对于乘法,*不可以省略)
map f [1..n] ,f x = 2 * x + 1可写成 map (\x-> 2*x+1) [1..n]
filter isEven [1..n] 可写成 filter (\x -> (mod x 2 == 0)) [1..n]
即isEven x = mod x 2 ==0 可写成 isEven = \x -> (mod x 2 == 0)
两个参数
add x = \y -> (x+y) <==>
add = \x -> (\y ->(x+y)) <==>
add = \x y -> (x+y)
(.) :: (b->c) ->(a->b)->a->c
f :: Int -> Int
f x = 2*x
isEven :: Int -> Bool
isEven x = mod x 2==0
f.isEven 是错误的,
isEven.f是正确的
isEven.f x等价于isEven (f x)等价于 isEven $ f x
f
g
h x = f (g (h x))
f . (g . h) = (f . g) . h,括号加的意义不明
.的使用:用于声明新函数时
he :: Int -> Bool
he = isEven.f
foldr 右结合,递归基写在左边,右边括号密
foldl 左结合,递归基写在右边,左边括号密
例子:
dec2int :: [Integer] -> Integer
dec2int = foldl (\ x y -> 10 * x + y) 0 (0代表[],即dec2int [] = 0) (foldl指取4和5,4为x,5为y,结果为y,上一个元素为x)
dec2int [2,3,4,5]
2345
计算顺序 (((((([]*10+2)*10)+3)*10)+4)*10)+5
记住foldl f z [x1, x2, …, xn] ==
(…((z f
x1) f
x2) f
…) f
xn
/*foldr :: (a->b->b)->b->[a] ->b
foldr f z []=z
foldr f z (x:xs) =f x (foldr f z xs)*/
记住foldr f z [x1, x2, …, xn] ==
x1 f
(x2 f
… (xn f
z)…)
foldr (-) 0 [1,2,3,4] (根据上面可知,f是相减,当为[]是0)
计算顺序 1-(2-(3-(4-[]))),[]=0
foldr (+) 0 [1..10] 得到55
例题1:
filter p=foldr (\x xs->if p x then x : xs else xs) []
解释:f为(\x xs->if p x then x : xs else xs) ,z为[]
假设只有两个元素[1,2],f为isEven
原式<==> x1 f
(x2 f
[]) <==>x1 f
(2:[]) <==>2:[]
例题2:
map f = foldl (\ xs x -> xs ++ [f x]) []
解释 : f 为(\ xs x -> xs ++ [f x]),z为[]
假设只有两个元素[1,2],f为isEven
原式<==> (z f
x1)f
x2 <==> ([] f
x1) f
x2 <==>([]++[isEven 1]) f
x2 <==> [False] f
2 <==> [False,True]
and xs = foldr (&&) True xs
或
and = foldr (&&) True
my_maximum :: Ord a => [a] ->a
my_maximum (x:xs) =mask (my_maximum xs)
concat :: [[a]] ->[a] (将列表的列表连成一个长列表)
concat =foldr (++) []
takewhile 从列表中取出元素直至不符合条件
takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2]
takeWhile (< 9) [1,2,3] == [1,2,3]
takeWhile (< 0) [1,2,3] == []
even 判断元素是否是偶数,返回Bool
odd判断元素是否是奇数
iterate f x == [x, f x, f (f x), …]