Haskell函数组成

时间:2009-09-25 07:27:58

标签: function haskell functional-programming composition

我正在阅读关于Haskell的this教程。他们将功能组合定义如下:

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

没有提供任何例子,我相信这会让我了解这里定义的内容。

有人可以提供一个关于如何使用函数组合的简单示例(有解释)吗?

6 个答案:

答案 0 :(得分:47)

函数组合是将两个函数“组合”成一个函数的方法。这是一个例子:

假设你有这些功能:

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]

更短,更少出错。

答案 1 :(得分:31)

有趣的旁注。函数组合相当于逻辑中的三段论:

  

所有人都是凡人。苏格拉底是个男人。因此,苏格拉底是凡人。

三段论将两个物质含义组合成一个:

(Man => Mortal), (Socrates => Man), therefore (Socrates => Mortal)

...因此

(b -> c) -> (a -> b) -> (a -> c)

...这是.函数的类型。

答案 2 :(得分:14)

fg组合是一个函数,首先将g应用于其参数,然后将f应用于返回的值g f。然后它返回f (g x) = (f . g) x的返回值。

这种身份可能具有启发性:

int f(int x);
int g(int x);
int theComposition(int x) { return f(g(x)); }

如果您有Java / C背景,请考虑以下示例:

{{1}}

答案 3 :(得分:7)

这个例子是设计的,但假设我们有

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)。

答案 4 :(得分:5)

函数组合是将两个或多个函数链接在一起的方法。它经常被比作贝壳管道。例如,在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

您基本上可以在任何可以使用任何其他功能的地方使用它。这只是一种快速可读的方式,可以说“我想将这些功能链接在一起”。

答案 5 :(得分:4)

来自HaskellWiki page on function composition:

desort = (reverse . sort)

现在desort是一个反向排序列表的函数。基本上,desort将其参数提供给sort,然后将sort的返回值反馈到reverse,返回该值。所以它对它进行排序,然后它反转排序列表。

相关问题