我正在阅读关于Haskell的this教程。他们定义函数组合如下所示:分别提供Haskell函数组合
(.) :: (b->c) -> (a->b) -> (a->c)
f . g = \ x -> f (g x)
没有例子,我相信会开导我,给正在这里定义的内容。
有人可以提供一个简单的例子(解释)如何使用函数组合?
我正在阅读关于Haskell的this教程。他们定义函数组合如下所示:分别提供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的需求。 E.g:
map (\x -> not (even x)) [1..9]
可以被改写为:
map (not . even) [1..9]
短一点,错误少的房间。
的组合物的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)); }
+1等效 – outis
从HaskellWiki page on function composition:
desort = (reverse . sort)
现在desort
是一个反向排序列表的函数。基本上,desort
将它的参数提供给sort
,然后将返回值从sort
提供到reverse
,返回值为。所以它对它进行排序,然后它反转排序的列表。
这个例子是人为的,但假设我们有
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)。
有趣的一面。功能组成相当于逻辑中的三段论:
所有的人都是凡人。苏格拉底是一个男人。因此,苏格拉底是致命的。
甲三段式构成两个材料影响到一个:
(Man => Mortal), (Socrates => Man), therefore (Socrates => Mortal)
因此...
(b -> c) -> (a -> b) -> (a -> c)
...这是.
功能的类型。
功能组合是将两个或更多功能链接在一起的一种方式。它通常被比作外壳管道。例如,在Unix风格的外壳,你可能会喜欢写东西
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
基本上你可以使用它的任何地方,你可以使用任何其他种类的功能。这只是一种快速而可读的说法,“我想将这些功能连在一起”。
你怎么不需要在定义中显示输入参数?例如。你怎么不写'myOdd x = not。甚至x'? – unclerojelio
@unclerojelio它被称为无点风格。根据给定参数的结果(“给定'x”,'myOdd'返回与'(not。even)x'“相同的值)来定义'myOdd',它是根据它实际是(“'myOdd'是'not'由'even'构成时的结果]”)。 – chepner