我是Haskell初学者,我想知道为什么我们可以在使用某些运算符时丢弃某些变量,例如:
last xs = head (reverse xs)
last' = head . reverse
另一个例子:
example p xs = length (filter p xs)
example' p = length . filter p
为什么我们不能在这个函数中抛出p?
答案 0 :(得分:6)
你没有“丢弃”那里的变量,你只是不提及它们。该过程称为eta-conversion:由于引用透明度,在您定义
时g x = f x
你也可以简单地写g = f
。当f
不是命名函数(如
last' xs = (head . reverse) xs
⇒ last' = head . reverse
但是这要求变量实际上只作为自包含函数的最终参数出现,例如:已经命名或包含在parens中的一个。例如,使用原始last
这是不可能的,因为xs
在括号(reverse xs)
中出现,因此您首先需要转换head (reverse xs) ≡ (head . reverse) xs
在你能减少它之前。同样地,
length . filter p ≡ length . (filter p)
所以你不能只减少p
,因为它在括号内。但是,正如bereal所建议的那样,您可以将预合成(length .)
视为应用于表达式其余部分的单独函数:
length . filter p
≡ (length .) (filter p)
≡ ((length .) . filter) p
example' = (length .) . filter
但我同意这会使代码更难阅读,因此我通常会保留example'
原样。
答案 1 :(得分:3)
这称为point-free notation。例如,它是:
example' = (length .) . filter
虽然在我看来很难理解。
有一个方便的工具可以生成无点版本:pointfree.io