我正在尝试从下一页http://dev.stephendiehl.com/hask/#universal-quantification了解通用量化的含义。
我不确定我是否能正确理解这句话
通用量化的本质是我们可以表达 对一组类型以相同方式操作的函数 功能行为完全取决于所有行为 在此范围内输入。
让我们从示例中获取功能:
-- ∀a. [a]
example1 :: forall a. [a]
example1 = []
我可以使用函数example1
来使用为列表类型定义的每个函数。
但是我没有得到Haskell通用量化的确切目的。
答案 0 :(得分:1)
我需要一个数字集合,并且我需要能够轻松地插入列表的中间,因此我决定制作一个链接列表。作为一个精明的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
的变体会很不错,那么我将再次复制并粘贴完全相同的代码,并调整特定于所包含类型的完全相同的位置。如果有一种方法可以一劳永逸地编写一个链表,它可以包含任何单一类型的元素,并且不管它有什么元素,长度函数都可以统一工作,那不是很好吗?毕竟,上面的length函数甚至根本不在乎元素具有什么值。在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元组的链表的函数的链表,...
多么好!现在,我们可以使用IntLinkedList
和FloatLinkedList
来代替单独的LinkedList Int
和LinkedList Float
类型,而一次实施的length_LinkedList
可以同时使用。 / p>