Haskell RankNTypes - 功能域的限制

use*_*029 3 polymorphism haskell rank-n-types

不明白为什么会这样,指的是:Rank2Types的目的是什么?-> @dfeuer 解释:

... 要求参数是多态的不仅允许它与多种类型一起使用;它还限制了该函数可以用它的参数做什么以及它如何产生它的结果......

f :: (forall a . [a] -> a) -> IO ()
Run Code Online (Sandbox Code Playgroud)

...事实上,没有函数返回不在给定列表中元素会进行类型检查

在对 rank-N 类型的任何解释中,我都没有看到这种效果(或好处)的描述,大部分时间是关于让被调用者选择类型等的故事......这对我来说很清楚并且易于掌握但是我看不出我们可以通过哪种美德(仅扩展等级)来控制/限制功能域(和共域)...

如果有人可以更深入地了解此处涉及的 rankN 机制。谢谢

lef*_*out 7

想想你在顶层声明的多态函数。带有签名的函数

foo :: [Int] -> Int
Run Code Online (Sandbox Code Playgroud)

有很多可能的实现,比如

foo = sum

foo = length

foo _ = 39
Run Code Online (Sandbox Code Playgroud)

但如果签名是合法的,这些都不合法

foo :: [a] -> a
Run Code Online (Sandbox Code Playgroud)

因为那样你就不能给出一个整数作为结果——你必须提供调用者要求的任何类型的结果。因此实现受到更多限制:结果必须来自输入列表,因为a无论调用者实际将其实例化为什么,这是您知道元素具有类型的唯一地方。只有像

foo = head
Run Code Online (Sandbox Code Playgroud)

然后会工作。

您的 RankN 签名要求其参数是这样的多态函数,即参数不能是 a ,[Int] -> Int而只能是更具限制性的[a] -> a

  • N...不,我认为你没有说对。它实际上与列表或其他什么没有任何关系。 (2认同)
  • @user3680029 我们有 `f :: (forall a . [a] -> a) -> IO ()`。在这个答案中,它的第一个参数被称为“foo”。它的类型是`foo :: [a] -> a`(隐含了`forall`)。给定一个列表 `[BigEnemy, MediumEnemy, PunyEnemy]`,`foo` 开始工作。那可能是什么?当我们编写它的定义时,我们不能使用关于 `BigEnemy` 类型的知识,因为 `foo` 必须适用于所有的 `a`。其他一些调用可以作为`foo [1,2,3,4]`。相同的定义也必须能够与该参数一起工作。 (2认同)