Haskell lambda 与 $ 与 函数组合

Category Haskell
Tag Haskell
Posted on
View

lambda

lambda就是匿名函数,有些时候我们会需要一个函数而这个函数可能只用到一次,并没有重用的场景,我们就可以搞一个 临时 的匿名函数来满足我们的计算。

(\xs -> length xs > 10)

lambda首先是一个\,后面是用空格分隔的参数,->后边就是函数体。通常会用括号括起来。

$

$函数,也叫作函数调用符,它的定义如下

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

普通的函数调用符有最高的优先级,而 $ 的优先级则最低。用空格的函数调用符是左结合的,如 f a b c 与 ((f a) b) c 等价,而 $ 则是右结合的

$是优先级最低的中缀右结合函数,从签名来看,只是个函数调用符,相当于在右边加括号

tip: $是个中缀函数,要求左边是函数,右边是其参数

> max 5 3 * 2 + 1
11
> max 5 $ 3 * 2 + 1
7
# 函数组合
函数组合用```.```函数来实现,```.```函数的定义为:

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

函数组合的用处之一就是生成新函数,并传递给其他函数。  
假设我们有一个数字组成的list,我们要把它其中每个元素转成负数,在使用函数组合之前我们可能会这样实现:

Prelude> map (\x -> negate (abs x)) [1,2,-3,4,5,-6] [-1,-2,-3,-4,-5,-6]

> tip: 先用abs函数取绝对值,再用negate函数取反

用函数组合的话就可以这样实现:

Prelude> map (negate . abs) [1,2,-3,4,5,-6] [-1,-2,-3,-4,-5,-6]

函数组合的另一用途就是定义 point free style (也称作 pointless style) 的函数。以下面的函数为例:

sum’ :: (Num a) => [a] -> a
sum’ xs = foldl (+) 0 xs

等号的两端都有个 xs。由于有柯里化 (Currying),我们可以省掉两端的 xs。foldl (+) 0 回传的就是一个取一 List 作参数的函数,我们把它修改为 sum' = foldl (+) 0,这就是 point free style。下面这个函数改成point free style就是:

fn x = ceiling (negate (tan (cos (max 50 x))))

fn = ceiling . negate . tan . cos . max 50 “`

来都来了说句话再走呗