Haskell lambda 与 $ 与 函数组合

2024-09-02 16:19:09 浏览数 (3)

lambda

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

代码语言:javascript复制
(xs -> length xs > 10)

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

$

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

代码语言:javascript复制
($) :: (a -> b) -> a -> b  
f $ x = f x  

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

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

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

代码语言:javascript复制
> max 5 3 * 2   1
11
> max 5 $ 3 * 2   1
7
代码语言:javascript复制
# 函数组合
函数组合用```.```函数来实现,```.```函数的定义为:

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

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

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

代码语言:javascript复制
> tip: 先用abs函数取绝对值,再用negate函数取反

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

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

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

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

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

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

代码语言:javascript复制

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

0 人点赞