[英]Why does function composition work when applied to functions that take multiple arguments?
我想我理解 function 应用程序在写出这些步骤时是如何工作的,但是类型签名算法并没有在我的脑海中加起来。 为漫长的前奏道歉(没有双关语)。
举一个具体的例子,这个来自Stefan Höck 的 Idris2 教程:
plusTwo : Integer -> Integer
plusTwo = (+2)
twice : (Integer -> Integer) -> Integer -> Integer
twice f n = f (f n)
在 REPL 中:
> twice plusTwo 3
7
> (twice . twice) plusTwo 3
11
Haskell 和 Idris 中的函数都是柯里化的,每个 function 只需要一个参数
function 组合实现为
f. g = \x -> f (gx)
function 应用程序是左关联的
类型签名中的箭头是右结合的
(twice. twice) plusTwo 3
表达式可以显式括起来为
((twice . twice) plusTwo) 3
可以重写为
------f-------- -n-
(twice (twice plusTwo)) 3
|
V
------f-------- (------f-------- -n-)
(twice plusTwo) ((twice plusTwo) 3 )
\------------------/
|||
plusTwo (plusTwo 3)
|||
7
\-----------------------------------/
|||
twice plusTwo 7
下面的 function 组合运算符的类型签名表明它采用单参数函数,
(.) :: (b -> c) -> (a -> b) -> a -> c
f . g = \x -> f (g x)
但是twice
需要两个 arguments (即(t -> t) -> t -> t
),所以这让我失望。
我想当返回的 lambda 的参数x
本身是 function 时,这是唯一可行的方法。 会不会这么简单?
twice . twice
((a -> a) -> a -> a) -> ((a -> a) -> a -> a) -> ?
(---b---- -> --c---) -> (---a---- -> --b---) -> (a -> c)
? = (a -> a) -> a -> a
或者,换句话说, twice. twice
twice. twice
采用带有签名(a -> a) -> a
的 function (这里a
是Integer
)。
如果上述内容是正确的,那么我可以找出 function 组合,其中参与函数具有不同的输入 arguments(例如, twice. (+2)
)。
是的,这就是全部。 如果你写twice
的签名可能会更容易思考
twice :: (Integer -> Integer) -> (Integer -> Integer)
如您所知,这与currying 是等价的。 这样看来, twice
是一个参数的 function,再次用twice
组合它似乎非常明智。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.