Haskell中的多态类型

时间:2017-08-03 13:50:41

标签: function haskell types polymorphism polymorphic-functions

我遇到了这个功能

iter p f x = if (p x) then x else (iter p f (f x))

我想我自己定义多态类型以理解这个概念。

我的想法如下:

该功能需要3个参数,因此我们有 t1 -> t2 -> t3 -> T

  1. p正在if条件中使用,因此必须返回bool,因此t1 = a -> Bool

  2. fp的类型相同,因为它在else块中作为参数传递,因此t2 = a -> Bool

  3. x在if条件中使用,因此必须返回bool,因此t1 = a -> Bool

  4. 但是当我检查ghci中的类型时,他们给我的类型是

    iter :: (t -> Bool) -> (t -> t) -> t -> t

    有人可以解释一下这背后的原因。

    由于

2 个答案:

答案 0 :(得分:5)

  

该函数有3个参数,所以我们有t1 - > t2 - > t3 - > Ť

这是正确的起点。

  

p正在if条件中使用,所以它必须返回一个bool,因此t1 = a - >布尔

正确。

  

f也是与p相同的类型,因为它在else块中作为参数传递,因此t2 = a - >布尔

不正确的。 f的使用方式与p的使用方式相同。在else块中,f被应用于x,结果作为iter的最后一个参数传递。据我们所知,f x必须与x的类型f :: a -> a相同。

  

x在if条件中使用,因此它必须返回bool,因此t1 = a - >布尔

不正确的。在if条件中,x仅用作p的参数。您在p :: a -> Bool之上建立了。因此x :: a

  

但是当我检查ghci中的类型时,他们给我的类型是

     

iter ::(t - > Bool) - > (t - > t) - > t - >吨

正确。您也可以将此t替换为a,以便在表示法中保持一致 - 我们使用上面的a

iter :: (a -> Bool) -> (a -> a) -> a -> a

答案 1 :(得分:1)

让我们再次评估一下:

iter p f x = if (p x) then x else (iter p f (f x))

iter有三个参数(从技术上讲,每个函数都有一个参数,但让我们跳过细节)。所以它确实有t1 -> t2 -> t3 -> t类型。

现在在if - then - else语句中,我们看到(p x)这意味着p x必须评估为布尔值。这意味着:

t1 ~ t3 -> Bool

接下来,我们在x语句中看到then。这可能是非重要的,但它是:它表示输出类型tt3的输出类型相同,因此:

t3 ~ t

现在这意味着我们已经派生出iter具有类型:

iter :: (t3 -> Bool) -> t2 -> t3 -> t3

现在我们在else语句中看到了电话:

iter p f (f x)

这意味着f是一个函数f :: t4 -> t5。由于它需要x作为输入,因此其输入类型应为t3,因为(f x)的结果会传递给iter函数(即 本身具有相同的“基础”iter 功能)。所以我们必须检查电话:

iter :: (u3 -> Bool) -> u2 -> u3 -> u3  -- call

现在我们用iter p f (f x)来称呼它,我们肯定知道u3 ~ t3:因为p的类型为t3 -> Bool。因此它进一步理由:

iter :: (t3 -> Bool) -> u2 -> t3 -> t3  -- call

正弦(f x)用作第三个参数,我们知道f x的结果类型也应该是t3。因此f的类型为f :: t3 -> t3。所以我们得出结论,iter的类型为:

iter :: (t3 -> Bool) -> (t3 -> t3) -> t3 -> t3