简体   繁体   English

Haskell中的多态类型

[英]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

  1. p is being used inside the if condition so it must return a bool , therefore t1 = a -> Bool p在if条件中使用,因此它必须返回bool ,因此t1 = a -> Bool

  2. f is also the same type as p because it is passed as an argument in the else block, therefore t2 = a -> Bool fp类型相同,因为它作为else块中的参数传递,因此t2 = a -> Bool

  3. 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: 这可能并不重要,但它是:这意味着输出类型tt3相同,因此:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM