[英]Haskell function composition
我正在阅读关于Haskell的本教程。 他们将功能组成定义如下:
(.) :: (b->c) -> (a->b) -> (a->c)
f . g = \ x -> f (g x)
我没有提供任何例子,我相信这会让我了解这里定义的内容。
有人能提供一个关于如何使用函数组合的简单示例(有解释)吗?
函数组合是将两个函数“组合”成一个函数的一种方法。 这是一个例子:
假设你有这些功能:
even :: Int -> Bool
not :: Bool -> Bool
并且你想使用上面的两个来定义你自己的myOdd :: Int -> Bool
函数。
显而易见的方法如下:
myOdd :: Int -> Bool
myOdd x = not (even x)
但是这可以使用函数组合更简洁地完成:
myOdd :: Int -> Bool
myOdd = not . even
myOdd
函数的行为完全相同,但第二个函数是通过将两个函数“粘合”在一起而创建的。
这个特别有用的场景是不需要显式的lambda。 例如:
map (\x -> not (even x)) [1..9]
可以改写为:
map (not . even) [1..9]
更短,更少的错误空间。
有趣的旁注。 函数组合相当于逻辑中的三段论:
所有人都是凡人。 苏格拉底是个男人。 因此,苏格拉底是凡人。
三段论将两个物质含义组合成一个:
(Man => Mortal), (Socrates => Man), therefore (Socrates => Mortal)
因此...
(b -> c) -> (a -> b) -> (a -> c)
... ...的类型.
功能。
of f
and g
is a function that first applies g
to its argument, then f
to the value returned by g
. 所述的 f
和g
是第一应用一个函数g
到它的参数,然后f
到由返回的值g
。 然后它返回f
的返回值。
这种身份可能具有启发性:
f (g x) = (f . g) x
如果您有Java / C背景,请考虑以下示例:
int f(int x);
int g(int x);
int theComposition(int x) { return f(g(x)); }
这个例子是人为的,但假设我们有
sqr x = x * x
inc x = x + 1
我们想写一个计算x ^ 2 + 1的函数。 我们可以写
xSquaredPlusOne = inc . sqr
(意思是
xSquaredPlusOne x = (inc . sqr) x
意思是
xSquaredPlusOne x = inc(sqr x)
因为f = inc和g = sqr)。
函数组合是将两个或多个函数链接在一起的方法。 它经常被比作贝壳管道。 例如,在Unix风格的shell中,你可能会写类似的东西
cat foo.txt | sort -n | less
这会运行cat
,将其输出提供给sort
,并将其输出提供给less
。
严格来说,这就像Haskell $
运算符。 你可能会写类似的东西
sum $ sort $ filter (> 0) $ my_list
请注意,与shell示例不同,它从右到左读取。 所以我们从my_list
开始作为输入,然后我们对它进行filter
,然后我们对它进行sort
,然后我们计算它的sum
。
函数组合运算符, .
,做类似的事情。 上面的例子产生了一个数字 ; 下面的例子产生一个函数 :
sum . sort . filter (> 0)
请注意,我们实际上没有将列表输入到此中。 相反,我们刚刚创建了一个新函数,我们可以为该函数提供几个不同的列表。 例如,您可以命名此函数:
my_function = sum . sort . filter (> 0)
或者您可以将其作为参数传递给另一个函数:
map (sum . sort . filter (> 0)) my_lists
您基本上可以在任何可以使用任何其他功能的地方使用它。 它只是一种快速且可读的方式来表达“我想将这些功能链接在一起”。
desort = (reverse . sort)
现在, desort
是一个反向排序列表的函数。 基本上, desort
将它的参数提供给sort
,然后将sort
的返回值反馈给reverse
,返回它。 所以它对它进行排序,然后它反转排序列表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.