[英]Type of f g x = g . g x
我不清楚为什么函数被定义为
f g x = g . g x
有类型
f :: (b -> a -> b) -> b -> a -> a -> b
我原以为它会是类型的
f :: (t -> t) -> t -> t
任何人都可以向我解释表达方式是如何分解的? 谢谢!
请注意,功能应用程序具有最高优先级; 经营者以后来。
所以,术语g . gx
g . gx
首先将g
应用于x
,然后组合结果和g
本身。 如果x
具有类型b
,则g
必须具有类型b -> c
。 由于我们用gx
(后者是c
类型)组成g
, c
必须是返回b
的函数类型,所以c = a -> b
。 现在, g
的类型是b -> a -> b
和g . gx
的类型g . gx
g . gx
是a -> (a -> b)
; f
的类型恰好是(b -> a -> b) -> b -> a -> a -> b
。
如果你想要(a -> a) -> a -> a
,你可以试试其中之一
f g x = g (g x)
f g x = (g . g) x
f g x = g . g $ x
f g = g . g
这个想法是关于理解(.)
运算符,它有一种类型
(.) :: (b -> c) -> (a -> b) -> a -> c
它需要两个函数,每个函数都有一个参数并组成它们,在应用gx
,编译器假定g
实际上是g :: a -> b -> c
,以满足(.) :: (b -> c) -> (a -> b) -> a -> c
的签名(.) :: (b -> c) -> (a -> b) -> a -> c
,它带有一个参数的两个函数。 否则代码将无法编译。
最后如果你想要签名f :: (t -> t) -> t -> t
你需要这样的东西:
λ> let applyTwice g = g.g
λ> :t applyTwice
applyTwice :: (a -> a) -> a -> a
λ> applyTwice (*2) 3
12
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.