我遇到了这个功能
iter p f x = if (p x) then x else (iter p f (f x))
我想我自己定义多态类型以理解这个概念。
我的想法如下:
该功能需要3个参数,因此我们有 t1 -> t2 -> t3 -> T
p
正在if条件中使用,因此必须返回bool
,因此t1 = a -> Bool
f
与p
的类型相同,因为它在else块中作为参数传递,因此t2 = a -> Bool
x在if条件中使用,因此必须返回bool,因此t1 = a -> Bool
但是当我检查ghci中的类型时,他们给我的类型是
iter :: (t -> Bool) -> (t -> t) -> t -> t
有人可以解释一下这背后的原因。
由于
答案 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
。这可能是非重要的,但它是:它表示输出类型t
与t3
的输出类型相同,因此:
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