我试图从下页http://dev.stephendiehl.com/hask/#universal-quantification中理解通用量化的含义。 。
我不确定我是否正确理解这句话
The essence of universal quantification is that we can express functions which operate the same way for a set of types and whose function behavior is entirely determined only by the behavior of all types in this span.
让我们从示例中获取该函数:
-- ∀a. [a]
example1 :: forall a. [a]
example1 = []
我可以用函数example1
做的是,使用为List类型定义的每个函数。
但是我没有得到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 的变体会很好,我将再次复制并粘贴完全相同的代码,并调整特定于的完全相同的位置所包含的类型。如果有一种方法可以一劳永逸地构建一个可以包含任何单一类型元素的链表,并且无论它有什么元素,长度函数都可以统一工作,那不是很好吗?毕竟,我们上面的长度函数甚至不关心元素有什么值。在 Haskell 中,这正是通用量化为您提供的:一种编写适用于整个类型集合的单个函数的方法。
它的外观如下:
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
链表、Float
链表, String
的链接列表,采用 FibbledyGibbets 并返回 Grazbars 和 WonkyNobbers 元组链接列表的函数链接列表,...
多好啊!现在,我们可以只使用 LinkedList Int
和 LinkedList Float
来代替单独的 IntLinkedList
和 FloatLinkedList
类型,并且length_LinkedList
,实现一次,适用于两者。
关于haskell - 通用量化的意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54883365/