haskell 递归和高阶函数

递归实际上是定义函数以调用自身的方式。 Haskell 没有 while 或 for 循环的原因,递归是我们的替代方案。

边界条件: 不递归的部分, 在递归定义中声明的一两个非递归的值
maximum' :: (Ord a) => [a] -> a   
maximum' [] = error "maximum of empty list"   
maximum' [x] = x   
maximum' (x:xs) = max x (maximum' xs)

固定模式:先定义一个边界条件,再定义个函数,让它从一堆元素中取一个并做点事情后,把余下的元素重新交给这个函数。

Haskell 中把函数可以作为参数和回传值传来传去,这样的函数就被称作高阶函数。


applyTwice :: (a -> a) -> a -> a   
applyTwice f x = f (f x)
ghci> applyTwice (+3) 10   
16 
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]   
zipWith' _ [] _ = []   
zipWith' _ _ [] = []   
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
flip' :: (a -> b -> c) -> (b -> a -> c)   
flip' f = g   
    where g x y = f y x

 (->) 是右结合. 用空格的函数调用符是左结合的,如 f a b c 与 ((f a) b) c 等价,而 $ 则是右结合的。函数组合(.)是右结合的


map :: (a -> b) -> [a] -> [b]   
map _ [] = []   
map f (x:xs) = f x : map f xs

filter :: (a -> Bool) -> [a] -> [a]   
filter _ [] = []   
filter p (x:xs)    
    | p x       = x : filter p xs   
    | otherwise = filter p xs

lambda 就是匿名函数

ghci> map (\(a,b) -> a + b) [(1,2),(3,5),(6,3),(2,6),(2,5)]   
[3,8,9,8,7]

sum' :: (Num a) => [a] -> a   
sum' xs = foldl (\acc x -> acc + x) 0 xs

elem' :: (Eq a) => a -> [a] -> Bool   
elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys

右折叠 foldr 的行为与左折叠相似,只是累加值是从 List 的右边开始。同样,左折叠的二元函数取累加值作首个参数,当前值为第二个参数(即 \acc x -> ...),而右折叠的二元函数参数的顺序正好相反(即 \x acc -> ...)。这倒也正常,毕竟是从右端开始折叠。

map' :: (a -> b) -> [a] -> [b]   
map' f xs = foldr (\x acc -> f x : acc) [] xs

scanl  和  scanr  与  foldl  和  foldr  相似,只是它们会记录下累加值的所有状态到一个 List。也有 scanl1  和  scanr1

ghci> scanl (+) 0 [3,5,2,1]   
[0,3,8,10,11]   
ghci> scanr (+) 0 [3,5,2,1]   
[11,8,3,1,0]   

(.) :: (b -> c) -> (a -> b) -> a -> c   
f . g = \x -> f (g x)

($) :: (a -> b) -> a -> b   
f $ x = f x


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值