混淆了haskell中的嵌套lambda类型

时间:2018-06-05 17:58:58

标签: haskell functional-programming

只是想看看像这样的一些lambda表达式的类型:

:t \x -> (\y -> x y)
\x -> (\y -> x y) :: (t1 -> t2) -> t1 -> t2

这里的类型不应该是t1->(t2->t1->t2)吗?

同样

:t \x -> (\y -> (\k -> y (x k)))
\x -> (\y -> (\k -> y (x k)))
  :: (t1 -> t2) -> (t2 -> t3) -> t1 -> t3

类型不应该是t1->(t2->(t3->t2))吗?

2 个答案:

答案 0 :(得分:3)

:t \x -> (\y -> x y)
\x -> (\y -> x y) :: (t1 -> t2) -> t1 -> t2
     

这里的类型不应该是t1->(t2-> t1-> t2)?

不,t1->(t2->t1->t2)t1->t2->t1->t2相同,t1是三参数函数的类型(t2t1t2类型)返回x。但是,对于两个参数ytypeOfX -> (typeofY -> typeOfResult) \x -> (\y -> x y) ,只有两个lambdas。

正确的类型是

typeOfResult

(顺便说一下,上面没有括号。)

什么是x y?是x的类型,因此它是typeOfX的返回类型,它必须是一个函数。

为了让代码键入check,我们必须让a -> b是一个函数类型,比如typeOfResult = b。在这种情况下,我们可以看到x y。此外,在y我们将x传递给typeOfY = a,这只能在typeOfX -> typeofY -> typeOfResult = (a -> b) -> a -> b 时进行检查。

所以,

t1

编译器使用了名称t2x,但这是相同的类型。

圆括号在这里很重要,因为我们必须记住a -> b是一个函数typeOfX -> typeofY -> typeOfK -> TypeOfResult。 如上所述,如果没有括号,我们将得到一个三参数函数。

您可以尝试将相同的推理应用于第二个示例。从...开始 toppings,慢慢发现这些类型实际上是什么。

答案 1 :(得分:0)

x中的\x -> \y -> x y类型为t1 -> t2,这是第一个参数。 作为最外面的lambda,首先应用它,然后是y

您可以将其编写为\x y -> x y,这只是自然顺序中的函数应用程序。