![](/img/trans.png)
[英]How can two similar functions have different polymorphic types in Haskell?
[英]Polymorphic types in Haskell
我碰到了这个功能
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条件中使用,因此它必须返回布尔值,因此t1 = a -> Bool
但是当我检查ghci的类型时,他们给我的类型是
iter :: (t -> Bool) -> (t -> t) -> t -> t
有人可以解释一下这背后的原因。
谢谢
该函数有3个参数,所以我们有t1-> t2-> t3-> T
这是正确的起点。
p在if条件中使用,因此它必须返回布尔值,因此t1 = a-> Bool
正确。
f与p的类型相同,因为它作为else块中的参数传递,因此t2 = a-> Bool
不正确 f
从未以与p
相同的方式使用。 在else块中,将f
应用于x
,并将结果作为最后一个参数传递给iter
。 由此我们知道fx
必须与x
具有相同的类型,所以f :: a -> a
。
x在if条件中使用,因此它必须返回布尔值,因此t1 = a-> Bool
不正确 在if条件中, x
仅用作p
的参数。 您在p :: a -> Bool
之上建立。 因此x :: a
。
但是当我检查ghci的类型时,他们给我的类型是
iter ::(t-> Bool)->(t-> t)-> t-> t
正确。 您也可以用a
代替t
来编写替换t
-我们a
上面使用a
:
iter :: (a -> Bool) -> (a -> a) -> a -> a
让我们再次评估一下:
iter p f x = if (p x) then x else (iter p f (f x))
iter
需要三个参数(从技术上讲,每个函数都需要一个参数,但让我们跳过细节)。 因此它确实具有类型t1 -> t2 -> t3 -> t
。
现在在if
- then
- else
语句中,我们看到(px)
这意味着px
必须计算为布尔值。 因此,这意味着:
t1 ~ t3 -> Bool
接下来,我们在then
语句中看到x
。 这可能并不重要,但它是:这意味着输出类型t
与t3
相同,因此:
t3 ~ t
现在这意味着我们已经得出iter
具有以下类型:
iter :: (t3 -> Bool) -> t2 -> t3 -> t3
现在我们在else
语句中看到调用:
iter p f (f x)
因此,意味着f
是函数f :: t4 -> t5
。 由于它将x
作为输入,因此其输入类型应该为t3
,并且由于(fx)
的结果传递给iter
函数( 本质上不是相同的“接地” iter
函数)。 因此,我们必须检查呼叫:
iter :: (u3 -> Bool) -> u2 -> u3 -> u3 -- call
现在,既然我们用iter pf (fx)
调用,我们肯定知道u3 ~ t3
:因为p
类型为t3 -> Bool
。 因此,它进一步基于:
iter :: (t3 -> Bool) -> u2 -> t3 -> t3 -- call
正弦(fx)
用作第三个参数,我们知道fx
结果的类型也应为t3
。 所以f
类型为f :: t3 -> t3
。 因此,我们得出结论:iter具有以下类型:
iter :: (t3 -> Bool) -> (t3 -> t3) -> t3 -> t3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.