了解Haskell的RankNTypes [英] Understanding Haskell's RankNTypes
问题描述
在通过GHC扩展工作的过程中,我遇到了 RankNTypes
在Haskell学院,有以下例子:
main = print $ rankN(+1)
rankN ::( forall n。num n => n - > n) - > (Int,Double)
rankN f =(f 1,f 1.0)
提供了另一种类型的 rankN
:
rankN :: forall n。 Num n => (n - > n) - > (Int,Double)
不同之处在于后一个签名需要一个对于某些Num n函数从n到n;前一个签名需要从n到n的函数,用于每个Num n。
我可以理解以前的类型要求签名是括号内的内容或更一般的内容。我不明白后面的签名只需要一个函数 n - >的解释。 n
代表一些 Num n
。有人可以详细说明吗?你如何读这个前签名,使其听起来像是什么意思?后者的签名是否与 Num n =>相同? (n - > n) - > (Int,Double)
,而不需要 forall
? ) - >(Int,Double)),我们选择 n
first ,然后提供一个函数。所以我们可以传入一个类型为 Int - >的函数。 Int
, Double - > Double
, Rational - >理性
等等。
在等级2的情况下((forall n。Num n => n - > n) - >(Int,Double)
),我们必须在 之前提供函数 。这意味着该函数必须适用于任何 n
;
我们需要这个例子给出的代码,因为函数 f $ c传入的$ c>应用于两种不同类型:
Int
和 Double
。所以它必须为他们两个工作。
第一种情况是正常的,因为这是默认情况下类型变量的工作方式。如果您根本没有 forall
,那么您的类型签名就等同于在开始时使用它。 (这被称为prenex形式。)因此 Num n => (n - > n) - > (Int,Double)
隐含地与 forall n相同。 Num n => (n - > n) - > (Int,Double)
。
名词
?这正是 forall n。 Num n => n - > n
。
While working my way through GHC extensions, I came across RankNTypes
at the School of Haskell, which had the following example:
main = print $ rankN (+1)
rankN :: (forall n. Num n => n -> n) -> (Int, Double)
rankN f = (f 1, f 1.0)
The article offered an alternative type for rankN
:
rankN :: forall n. Num n => (n -> n) -> (Int, Double)
The explanation of the difference is that "The latter signature requires a function from n to n for some Num n; the former signature requires a function from n to n for every Num n."
I can understand that the former type requires a signature to be what's in the parentheses or more general. I do not understand the explanation that the latter signature simply requires a function n -> n
for "some Num n
". Can someone elaborate and clarify? How do you "read" this former signature so that it sounds like what it means? Is the latter signature the same as simply Num n => (n -> n) -> (Int, Double)
without the need for forall
?
In the normal case (forall n. Num n => (n -> n) -> (Int, Double)
), we choose an n
first and then provide a function. So we could pass in a function of type Int -> Int
, Double -> Double
, Rational -> Rational
and so on.
In the Rank 2 case ((forall n. Num n => n -> n) -> (Int, Double)
) we have to provide the function before we know n
. This means that the function has to work for any n
; none of the examples I listed for the previous example would work.
We need this for the example code given because the function f
that's passed in is applied to two different types: an Int
and a Double
. So it has to work for both of them.
The first case is normal because that's how type variables work by default. If you don't have a forall
at all, your type signature is equivalent to having it at the very beginning. (This is called prenex form.) So Num n => (n -> n) -> (Int, Double)
is implicitly the same as forall n. Num n => (n -> n) -> (Int, Double)
.
What's the type of a function that works for any n
? It's exactly forall n. Num n => n -> n
.
这篇关于了解Haskell的RankNTypes的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!