了解Haskell的RankNTypes [英] Understanding Haskell's RankNTypes

查看:84
本文介绍了了解Haskell的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 应用于两种不同类型: 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆