Haskell 普遍量化的意义

Haskell 普遍量化的意义,haskell,types,polymorphism,parametric-polymorphism,Haskell,Types,Polymorphism,Parametric Polymorphism,我试图从下一页理解普遍量化的含义 我不确定我是否正确理解了这个句子 普遍量化的本质是我们可以表达 对一组类型以相同方式操作的函数,其 函数行为完全由所有函数的行为决定 此范围中的类型 让我们从示例中选取函数: -- ∀a. [a] example1 :: forall a. [a] example1 = [] 使用函数example1可以使用为列表类型定义的每个函数 但我并没有在Haskell中得到普遍量化的确切目的 我需要一组数字,并且我需要能够轻松地插入列表的中间,所以我决定制作一个链表

我试图从下一页理解普遍量化的含义

我不确定我是否正确理解了这个句子

普遍量化的本质是我们可以表达 对一组类型以相同方式操作的函数,其 函数行为完全由所有函数的行为决定 此范围中的类型

让我们从示例中选取函数:

-- ∀a. [a]
example1 :: forall a. [a]
example1 = [] 
使用函数
example1
可以使用为列表类型定义的每个函数


但我并没有在Haskell中得到普遍量化的确切目的

我需要一组数字,并且我需要能够轻松地插入列表的中间,所以我决定制作一个链表。作为一个精明的Hask——程序员(Hask——Haskell的变体,它没有通用的量化!),我很快就创建了一个类型和一个长度函数:

data IntLinkedList = IntNil | IntCons Int IntLinkedList

length_IntLinkedList :: IntLinkedList -> Int
length_IntLinkedList IntNil = 0
length_IntLinkedList (IntCons _ tail) = 1 + length_IntLinkedList tail
后来我意识到,有一种变体类型可以方便地存储大小不到1、大小不到0的数字。没问题

data FloatLinkedList = FloatNil | FloatCons Float FloatLinkedList

length_FloatLinkedList :: FloatLinkedList -> Int
length_FloatLinkedList FloatNil = 0
length_FloatLinkedList (FloatCons _ tail) = 1 + length_FloatLinkedList tail
男孩,代码看起来非常熟悉!如果以后我发现有一个可以存储
String
s的变体会很好,我将再次复制和粘贴完全相同的代码,并调整特定于所包含类型的完全相同的位置。如果有一种方法可以一劳永逸地创建一个链表,其中可以包含任何单一类型的元素,并且有一个长度函数,该函数无论包含什么元素都可以统一工作,这难道不是很好吗?毕竟,上面的长度函数甚至不关心元素的值。在Haskell中,这正是universal quantification提供给您的:一种编写单个函数的方法,该函数可以处理整个类型集合

下面是它的外观:

data LinkedList a = Nil | Cons a (LinkedList a)

length_LinkedList :: forall a. LinkedList a -> Int
length_LinkedList Nil = 0
length_LinkedList (Cons _ tail) = 1 + length_LinkedList tail
forall
表示此函数适用于链表的所有变体--
Int
s的链表、
Float
s的链表、
String
s的链表、
String
s的链表、采用FibbledyGibbets并返回Grazbar和Wonkynobers元组链表的函数链表


多好啊!现在,我们可以使用
LinkedList Int
LinkedList Float
来代替单独的
IntLinkedList
LinkedList Float
,并且一次实现的
length\u LinkedList
对这两种类型都有效。

example1
没有函数。这只是一张空名单。需要指出的一点是,这实际上是一个“多态常量”(很像数字文字),对于任何类型
a
,它都可以有类型
[a]
。实际上,您不需要将
用于所有a.
(或链接到的页面上的任何示例中),因为Haskell会隐式地理解它。但是一旦你进入等级2(或更高)类型,你确实需要对所有的s进行明确的
。注意该部分前面的警告。注意关键字
forall
出现在类型签名的两个完全不同的上下文中(这让我很困惑):要么是通用量化,在这种情况下通常是可选的;或者它是存在量化/
秩2
(或更高)类型,在这种情况下它是必需的。@RobinZigmond个人来说,我更喜欢“多态常量定义”。也就是说,它是一个能够为任何特定的
a
选择定义空列表
[]:[a]
常量的定义。(或者应该是
A
?)。这就为这样一个问题敞开了大门:“那么,如果我要做的只是测量它的长度,为什么我不能将int、float和字符串的列表混合在一起?”!这就是存在主义量化的目的,哈斯克尔也有这一点。但是zero_编码询问的是通用量化,而不是存在性……我的目标更多的是多态类型的本质,为什么列表必须是同质的,等等。我希望你能对此有所了解。我不需要存在类型来度量长度。或者拉拉链。它可能涉及到静态类型与动态类型的核心…?@Willence A koan可能会将您的想法集中在这个主题上:对于任何算法,您根本不需要类型。那么,它们有什么好处呢?我理解HM在这方面的态度,但肯定有两个以上的边缘点。想象一下
让xs=[(1,True),((2,False)]进入(map fst$filter snd xs,map fst$filter(not.snd)xs)
。最终结果类型正确,有意义。如果列表操作函数应该只执行结构操作,那么它们为什么要关注列表的同质性呢?HM说,好吧,但这样的清单在事后无论如何都没有意义。我的例子表明,它们可能是。随着项目的进展,相关价值观的特征可能会逐渐被发现。。。等