我如何找出Haskell函数的类型?

时间:2017-07-19 18:43:05

标签: haskell types functional-programming type-inference lambda-calculus

目前我正在为我的考试做准备,这是关于Haskell的一些我从未真正理解过的东西。

类型规则如下

“und”在德语中的意思是“和”。

所以给定的函数是

f :: ([a] -> b) -> a -> [b]
g :: c -> Int -> c

现在我必须使用上面的类型规则来确定类型(f g)。有人可以解释我现在该如何进行吗?

1 个答案:

答案 0 :(得分:4)

为了快速回顾,我们知道这些事实:

  1. 如果s :: sigma -> tau
    t :: rho
    gamma(sigma) = gamma(rho)
    然后s t :: gamma(tau)
  2. f :: ([a] -> b) -> a -> [b]
  3. g :: c -> Int -> c
  4. 我们想了解f g的类型。看起来规则(1)可以告诉我们,如果我们选择stsigmataurhogamma适当。让我们对我们如何恰当地设置它们并看看它在哪里引导我们进行一些猜测。

    • 由于(1)的结论是s t :: ...,我们想知道f g :: ...,我们应该选择s = ft = g
    • 由于(1)的前提是s :: sigma -> tau并且我们已选择s = f并且知道{2}中的f :: ([a] -> b) -> a -> [b],我们应该选择sigma = [a] -> btau = a -> [b]
    • 由于(1)的前提是t :: rho,我们已选择t = g并且知道{3}中的g :: c -> Int -> c,我们应该选择rho = c -> Int -> c

    总结我们的选择,我们现在将(1)转换为这种形式:

    如果f :: ([a] -> b) -> a -> [b]
    g :: c -> Int -> c
    gamma([a] -> b) = gamma(c -> Int -> c)
    然后f g :: gamma(a -> [b])

    在(1)中只有一个变量我们还没有选择一个值,即gamma。第三个前提稍微约束gamma,即它必须满足:

    gamma([a] -> b) = gamma(c -> Int -> c)
    

    据推测,有一个隐含的假设,即它的行为类似于替换,即在类型结构上进行递归并替换类型变量,因此先前的等式假设等同于此:

    [gamma(a)] -> gamma(b) = gamma(c) -> Int -> gamma(c)
    

    要使这个等式成立,我们必须拥有所有这些东西:

    gamma(c) = [gamma(a)]
    gamma(b) = Int -> gamma(c) = Int -> [gamma(a)]
    

    如果我们为gamma(a)做出任意选择,这些等式会告诉我们gamma(b)gamma(c)的结果;让我们选择gamma(a) = a。然后:

    gamma(a) = a
    gamma(b) = Int -> [a]
    gamma(c) = [a]
    

    现在我们已经满足了(1)的前提,因此我们得出结论:

    f g :: gamma(a -> [b])
    f g :: gamma(a) -> [gamma(b)]
    f g :: a -> [Int -> [a]]