eve*_*hav 3 lambda haskell types
我想了解如何手动获取此 Haskell 表达式的正确类型。
(\x y z -> (x y) z)
Run Code Online (Sandbox Code Playgroud)
一般来说,我大致了解如何手动确定正确的类型,但对于 lambda 表达式,我完全感到困惑。
有一种快速获取类型的方法和一种缓慢的方法。缓慢的方式在下面,不会删除任何不必要的括号。
让我们记住 Haskell 函数的属性,即
f :: a -> b -> c
Run Code Online (Sandbox Code Playgroud)
这两个f x y和(f x) y是相同的,因为a -> b -> c是a -> (b -> c)。
因此\x y z -> (x y) z与 相同\x y z -> x y z。因此,如果y's 和z's 类型 wherea和bresp.,则x's 类型是a -> b -> c:
\x y z -> x y z :: (a -> b -> c) -> a -> b -> c
Run Code Online (Sandbox Code Playgroud)
如果我们命名该函数,那么我们会这样写:
f :: (a -> b -> c) -> a -> b -> c
f x y z = x y z
Run Code Online (Sandbox Code Playgroud)
甚至更简单:
f :: (a -> b -> c) -> a -> b -> c
f = id
Run Code Online (Sandbox Code Playgroud)
因为它是一个函数类型的识别函数。您可以添加左右括号a -> b -> c中的类型看,由于a -> b -> c是a -> (b -> c):
f :: (a -> b -> c) -> (a -> b -> c)
f = id
Run Code Online (Sandbox Code Playgroud)
让我们首先为 lambda 命名。这将使我们能够使用类型签名并从那里继续:
f = \x y z -> (x y) z
Run Code Online (Sandbox Code Playgroud)
接下来,我们使用常规函数语法而不是 lambda 语法:
f :: A -> B -> C -> D
f x y z = (x y) z
Run Code Online (Sandbox Code Playgroud)
现在,我们需要弄清楚A,B,C和D。由于x应用于y,我们注意到它A必须是某种函数类型,例如B -> ...?。接下来我们注意到它x y也必须是一个函数。因此,A需要是B -> G,并且G需要再次成为一个函数。由于G能够使用z,因此是一个 type 值C,我们知道它G是G = C -> D:
f :: (B -> (C -> D)) -> B -> C -> D
Run Code Online (Sandbox Code Playgroud)
我们现在有x的类型,它是B -> (C -> D)。由于既不约束y也不z约束,我们现在可以将所有类型占位符更改为类型变量并最终得到:
f :: (b -> (c -> d)) -> b -> c -> d
f x y z = (x y) z
Run Code Online (Sandbox Code Playgroud)
最后一步,让我们重命名这些变量:
f :: (a -> (b -> c)) -> a -> b -> c
f x y z = (x y) z
Run Code Online (Sandbox Code Playgroud)
这就是\x y z -> (x y) z类型:(a -> (b -> c)) -> a -> b -> c。
| 归档时间: |
|
| 查看次数: |
52 次 |
| 最近记录: |