有人可以解释1(1+)0
在haskell.org我碰到这点*风格的函数来了(()$())(==)的含义,被称为 “猫头鹰”。有人可以解释1(1+)0
((.)$(.))
它的类型签名是 (a -> b -> c) -> a -> (a1 -> b) -> a1 -> c
。
这相当于 f a b c d = a b (c d)
显然, ((.)$(.)) (==) 1 (1+) 0
回报True
。
所以我的问题是:
- 是什么在类型签名
a1
是什么意思?它与a
有关吗? - 是
(==)
某种功能相等运算符的?因为0 (==) 0
在GHCi中引发错误。 -
1 (1+) 0
这是什么意思?我不明白这是甚么有效的表达。 - 为什么表达式返回
True
?
的
a1
“只是另一种类型的变量”。这可能意味着什么,包括a
,但不一定意味着什么。最有可能与a
不同。(==)
是==
的“强制前缀”形式,常规等于运算符构成Eq
类型的类。通常你会写a == b
,但这仅仅是(==) a b
的语法糖,其前缀应用为==
。1 (1+) 0
在这种情况下并不意味着什么,三个子表达式中的每一个都是对“猫头鹰”的独立论证,最终有四个论点。-
我们可以通过减少行走。
((.)$(.)) (==) 1 (1+) 0 === [ apply ] ((.)(.)) (==) 1 (1+) 0 === [ implicit association ] ((.)(.)(==)) 1 (1+) 0 === [ apply the definition: (f.g) x = f (g x) ] ((.) (1 ==)) (1+) 0 === [ implicit association ] ((.) (1 ==) (1+)) 0 === [ apply the definition: (f.g) x = f (g x) ] 1 == (1+0) === [addition] 1 == 1 === [equality] True
由于this page提到,猫头鹰就相当于一个功能f
f a b c d = a b (c d)
这就是说它适用其第一个参数的两个参数的函数,其第二个论点和将第三个论点应用于第四个论证的结果。对于这意味着你首先应用(+1)
到0
给出((.)$(.)) (==) 1 (1+) 0
的例子,然后再结合1
和使用(==)
这是我们减少发生了什么(1+0)
。
更广泛地说,你可以把它作为修改二元运算a
采取第二个参数稍有变化的功能。
我明白了,我忘记了强制前缀。我认为这是正常意义上的括号。感谢您的评估演练 –
Nit:'(==)1'是'(1 ==)',而不是'(== 1)'。不是说它对'=='的默认定义很重要,但... –
好点!固定。 –
首先,我们写_B f g x = f (g x) = (f . g) x
。
由于f $ x = f x
,我们有(.)$(.) = _B $ _B = _B _B
。其类型被机械地衍生,如
0. (.) :: ( b -> c ) -> ((a -> b) -> (a -> c))
1. (.) :: (b1 -> c1) -> ((a1 -> b1) -> (a1 -> c1))
2. (.) (.) :: {b ~ b1 -> c1, c ~ (a1 -> b1) -> (a1 -> c1)} (a -> b) -> (a -> c)
:: (a -> b1 -> c1) -> a -> (a1 -> b1) -> (a1 -> c1)
:: (a -> b -> c) -> a -> (a1 -> b) -> a1 -> c
a
和a1
是两个不同类型的变量,就像b
和b1
。但由于最终类型中没有b
或c
,我们可以将b1
和c1
重新命名为b
和c
,以简化。但不是a1
。
实际上我们可以读到这个类型:它获得了一个二元函数f :: a -> b -> c
; x :: a
参数值,g :: a1 -> b
一元函数,和另一个值y :: a1
,并结合他们唯一可能的方式,这样的类型适合:
f x :: b -> c
g y :: b
f x (g y) :: c
其余部分已经回答。通常在组合方程式中可以很容易地使用简化方法,例如_B _B f x g y = _B (f x) g y = f x (g y)
,只需要两个应用_B
的定义(我们可以随时添加尽可能多的参数)。
请注意'((。)$(。))'中的'$'是不必要的;表达式'((。)(。))'是完全等价的。 –