我试图在Haskell中学习函数组合。我有以下练习
我有函数:h x y = f (g x y)
,我需要找到与它相等的函数组合:
a) f . g
b) (f.).g
c) (.)f(.g)
d) f(.g)
我知道(.)f g = f.g = f(g x)
但我不理解这种复杂的功能构成
答案 0 :(得分:4)
正确答案是(b):(f.).g
让我们分析一下这个功能。 (f.)
部分是((.) f)
的缩写,所以我们已经解决了这个问题,因此函数 - 没有语法糖 - 是:
(.) ((.) f) g
现在我们可以将第一个(.)
函数重写为lambda表达式:
\x -> ((.) f) (g x)
现在当我们进一步评估左边的第二个函数(((.) f)
)时,我们得到:
\x -> (.) f (g x)
或:
\x -> f . g x
因此,如果我们在lambda表达式中转换(.)
函数,我们得到:
\x -> (\y -> f ((g x) y))
现在我们可以使这个表达更优雅。 (g x) y
可以重写为g x y
:
\x -> (\y -> f (g x y))
我们可以将嵌套的lambda表达式重写为单个lambda表达式:
\x y -> f (g x y)
这就是我们想要的。
答案 1 :(得分:3)
您也可以使用(.) (.) (.)
- 尽管它有点challenging to understand,但评估会产生与您正在寻找的优雅形式相同的优雅形式
comp2 = (.) (.) (.)
comp2 f g x y == f (g x y)
评估(.) (.) (.)
-- comp
(.) = \f -> \g -> x -> f (g x)
-- evaluate
(.) (.) (.)
(\f -> \g -> \x -> f (g x)) (.) (.)
(\g -> \x -> (.) (g x)) (.)
\x -> (.) ((.) x)
\x -> (\f -> \g -> \x' -> f (g x')) ((.) x)
\x -> \g -> \x' -> ((.) x) (g x')
\x -> \g -> \x' -> ((\f -> \g' x'' -> f (g' x'')) x) (g x')
\x -> \g -> \x' -> (\g' -> \x'' -> x (g' x'')) (g x')
\x -> \g -> \x' -> \x'' -> x ((g x') x'')
\x -> \g -> \x' -> \x'' -> x (g x' x'')
-- alpha rename
\f -> \g -> \x -> \y -> f (g x y)
-- collapse lambdas
\f g x y -> f (g x y)
了解(.)
作品的模式
-- comp2
comp2 = (.) (.) (.)
comp2 f g x y == f (g x y)
-- comp3
comp3 = (.) (.) comp2
comp3 f g x y z == f (g x y z)
-- comp4
comp4 = (.) (.) comp3
comp4 f g w x y z == f (g w x y z)