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 条件中使用,因此它必须 return 一个 bool
,因此 t1 = a -> Bool
f
也是与 p
相同的类型,因为它在 else 块中作为参数传递,因此 t2 = a -> Bool
x 在 if 条件中使用,所以它必须 return 一个布尔值,因此 t1 = a -> Bool
但是当我检查ghci中的类型时,他们给我的类型是
iter :: (t -> Bool) -> (t -> t) -> t -> t
谁能解释一下这背后的原因。
谢谢
The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T
这是正确的起点。
p is being used inside the if condition so it must return a bool, therefore 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 块中,f
被应用于 x
,结果作为最后一个参数传递给 iter
。由此我们知道 f x
必须与 x
的类型相同,所以 f :: a -> a
.
x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
不正确。在 if 条件中 x
仅用作 p
的参数。你在上面建立了p :: a -> Bool
。因此x :: a
.
But when i checked the type in the ghci, the type they gave me was
iter :: (t -> Bool) -> (t -> t) -> t -> 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). So it has indeed a type t1 -> t2 -> t3 -> t
.
Now in the if
-then
-else
statement, we see (p x)
this means that p x
has to evaluate to a boolean. So that means that:
t1 ~ t3 -> Bool
Next we see x
in the then
statement. This may strike as non-important, but it is: it means that the output type t
is the same as that of t3
, so:
t3 ~ t
Now that means we already derived that iter
has the type:
iter :: (t3 -> Bool) -> t2 -> t3 -> t3
Now we see in the else
statement the call:
iter p f (f x)
So that means that f
is a function f :: t4 -> t5
. Since it takes x
as input, its input type should be t3
, and since the result of (f x)
is passed to an iter
function (that is not per se the same "grounded" iter
function). So we have to inspect the call:
iter :: (u3 -> Bool) -> u2 -> u3 -> u3 -- call
Now since we call it with iter p f (f x)
we definitely know that u3 ~ t3
: because p
has type t3 -> Bool
. So it grounds further to:
iter :: (t3 -> Bool) -> u2 -> t3 -> t3 -- call
Sine (f x)
is used as third argument, we know that the type of the result of f x
should be t3
as well. So f
has type f :: t3 -> t3
. So we conclude that iter has the type:
iter :: (t3 -> Bool) -> (t3 -> t3) -> t3 -> t3
我遇到了这个函数
iter p f x = if (p x) then x else (iter p f (f x))
我想我应该自己定义多态类型来理解这个概念。
我的想法如下:
函数有3个参数,所以我们有t1 -> t2 -> t3 -> T
p
在 if 条件中使用,因此它必须 return 一个bool
,因此t1 = a -> Bool
f
也是与p
相同的类型,因为它在 else 块中作为参数传递,因此t2 = a -> Bool
x 在 if 条件中使用,所以它必须 return 一个布尔值,因此
t1 = a -> Bool
但是当我检查ghci中的类型时,他们给我的类型是
iter :: (t -> Bool) -> (t -> t) -> t -> t
谁能解释一下这背后的原因。
谢谢
The function takes 3 parameters, so we have t1 -> t2 -> t3 -> T
这是正确的起点。
p is being used inside the if condition so it must return a bool, therefore 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 块中,f
被应用于 x
,结果作为最后一个参数传递给 iter
。由此我们知道 f x
必须与 x
的类型相同,所以 f :: a -> a
.
x is being used inside the if condition so it must return a bool, therefore t1 = a -> Bool
不正确。在 if 条件中 x
仅用作 p
的参数。你在上面建立了p :: a -> Bool
。因此x :: a
.
But when i checked the type in the ghci, the type they gave me was
iter :: (t -> Bool) -> (t -> t) -> t -> 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). So it has indeed a type t1 -> t2 -> t3 -> t
.
Now in the if
-then
-else
statement, we see (p x)
this means that p x
has to evaluate to a boolean. So that means that:
t1 ~ t3 -> Bool
Next we see x
in the then
statement. This may strike as non-important, but it is: it means that the output type t
is the same as that of t3
, so:
t3 ~ t
Now that means we already derived that iter
has the type:
iter :: (t3 -> Bool) -> t2 -> t3 -> t3
Now we see in the else
statement the call:
iter p f (f x)
So that means that f
is a function f :: t4 -> t5
. Since it takes x
as input, its input type should be t3
, and since the result of (f x)
is passed to an iter
function (that is not per se the same "grounded" iter
function). So we have to inspect the call:
iter :: (u3 -> Bool) -> u2 -> u3 -> u3 -- call
Now since we call it with iter p f (f x)
we definitely know that u3 ~ t3
: because p
has type t3 -> Bool
. So it grounds further to:
iter :: (t3 -> Bool) -> u2 -> t3 -> t3 -- call
Sine (f x)
is used as third argument, we know that the type of the result of f x
should be t3
as well. So f
has type f :: t3 -> t3
. So we conclude that iter has the type:
iter :: (t3 -> Bool) -> (t3 -> t3) -> t3 -> t3