[英]Polymorphic types in Haskell
I came across this function 我碰到了这个功能
iter p f x = if (p x) then x else (iter p f (f x))
and I thought I'd give a go at defining the polymorphic types myself to understand the concept. 我以为自己可以自己定义多态类型以理解这个概念。
My thought was the following: 我的想法是:
The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T
该函数有3个参数,所以我们有
t1 -> t2 -> t3 -> T
p
is being used inside the if condition so it must return a bool
, therefore t1 = a -> Bool
p
在if条件中使用,因此它必须返回bool
,因此t1 = a -> Bool
f
is also the same type as p
because it is passed as an argument in the else block, therefore t2 = a -> Bool
f
与p
类型相同,因为它作为else块中的参数传递,因此t2 = a -> Bool
x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
x在if条件中使用,因此它必须返回布尔值,因此
t1 = a -> Bool
But when i checked the type in the ghci, the type they gave me was 但是当我检查ghci的类型时,他们给我的类型是
iter :: (t -> Bool) -> (t -> t) -> t -> t
Can someone please explain the reasoning behind this. 有人可以解释一下这背后的原因。
Thanks 谢谢
The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T
该函数有3个参数,所以我们有t1-> t2-> t3-> T
This is correct as a starting point. 这是正确的起点。
p is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
p在if条件中使用,因此它必须返回布尔值,因此t1 = a-> Bool
Correct. 正确。
f is also the same type as p because it is passed as an argument in the else block, therefore t2 = a -> Bool
f与p的类型相同,因为它作为else块中的参数传递,因此t2 = a-> Bool
Incorrect. 不正确
f
is never used in the same way as p
. f
从未以与p
相同的方式使用。 In the else block f
is being applied to x
and the result passed as the last argument to iter
. 在else块中,将
f
应用于x
,并将结果作为最后一个参数传递给iter
。 From that we know fx
must be the same type as x
so f :: a -> a
. 由此我们知道
fx
必须与x
具有相同的类型,所以f :: a -> a
。
x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
x在if条件中使用,因此它必须返回布尔值,因此t1 = a-> Bool
Incorrect. 不正确 In the if condition
x
is being used only as an argument to p
. 在if条件中,
x
仅用作p
的参数。 You established above p :: a -> Bool
. 您在
p :: a -> Bool
之上建立。 Therefore x :: a
. 因此
x :: a
。
But when i checked the type in the ghci, the type they gave me was
但是当我检查ghci的类型时,他们给我的类型是
iter :: (t -> Bool) -> (t -> t) -> t -> t
iter ::(t-> Bool)->(t-> t)-> t-> t
Correct. 正确。 You could also write this replacing
t
with a
to be consistent in the notation - we used a
above: 您也可以用
a
代替t
来编写替换t
-我们a
上面使用a
:
iter :: (a -> Bool) -> (a -> a) -> a -> a
Let's evaluate it again: 让我们再次评估一下:
iter p f x = if (p x) then x else (iter p f (f x))
iter
takes three parameters (well technically speaking every function takes one parameter, but let's skip the details). iter
需要三个参数(从技术上讲,每个函数都需要一个参数,但让我们跳过细节)。 So it has indeed a type t1 -> t2 -> t3 -> t
. 因此它确实具有类型
t1 -> t2 -> t3 -> t
。
Now in the if
- then
- else
statement, we see (px)
this means that px
has to evaluate to a boolean. 现在在
if
- then
- else
语句中,我们看到(px)
这意味着px
必须计算为布尔值。 So that means that: 因此,这意味着:
t1 ~ t3 -> Bool
Next we see x
in the then
statement. 接下来,我们在
then
语句中看到x
。 This may strike as non-important, but it is: it means that the output type t
is the same as that of t3
, so: 这可能并不重要,但它是:这意味着输出类型
t
与t3
相同,因此:
t3 ~ t
Now that means we already derived that iter
has the type: 现在这意味着我们已经得出
iter
具有以下类型:
iter :: (t3 -> Bool) -> t2 -> t3 -> t3
Now we see in the else
statement the call: 现在我们在
else
语句中看到调用:
iter p f (f x)
So that means that f
is a function f :: t4 -> t5
. 因此,意味着
f
是函数f :: t4 -> t5
。 Since it takes x
as input, its input type should be t3
, and since the result of (fx)
is passed to an iter
function (that is not per se the same "grounded" iter
function). 由于它将
x
作为输入,因此其输入类型应该为t3
,并且由于(fx)
的结果传递给iter
函数( 本质上不是相同的“接地” iter
函数)。 So we have to inspect the call: 因此,我们必须检查呼叫:
iter :: (u3 -> Bool) -> u2 -> u3 -> u3 -- call
Now since we call it with iter pf (fx)
we definitely know that u3 ~ t3
: because p
has type t3 -> Bool
. 现在,既然我们用
iter pf (fx)
调用,我们肯定知道u3 ~ t3
:因为p
类型为t3 -> Bool
。 So it grounds further to: 因此,它进一步基于:
iter :: (t3 -> Bool) -> u2 -> t3 -> t3 -- call
Sine (fx)
is used as third argument, we know that the type of the result of fx
should be t3
as well. 正弦
(fx)
用作第三个参数,我们知道fx
结果的类型也应为t3
。 So f
has type f :: t3 -> t3
. 所以
f
类型为f :: t3 -> t3
。 So we conclude that iter has the type: 因此,我们得出结论:iter具有以下类型:
iter :: (t3 -> Bool) -> (t3 -> t3) -> t3 -> t3
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.