Смысл универсального количественного определения - PullRequest
0 голосов
/ 26 февраля 2019

Я пытаюсь понять значение универсального количественного определения со следующей страницы http://dev.stephendiehl.com/hask/#universal-quantification.

Я не уверен, правильно ли я понимаю это предложение

Суть универсального количественного определения заключается в том, что мы можем выражать функции, которые работают одинаково для набора типов и поведение функций которых полностью определяется только поведением всех типов в этом диапазоне.

Давайте возьмем функцию из примера:

-- ∀a. [a]
example1 :: forall a. [a]
example1 = [] 

Что я могу сделать с функцией example1, так это использовать все функции, определенные для Listтип.

Но я не понял цели универсального количественного определения в Хаскеле.

1 Ответ

0 голосов
/ 26 февраля 2019

Мне нужна коллекция чисел, и я должен иметь возможность легко вставить ее в середину списка, поэтому я решил создать связанный список.Будучи опытным программистом на 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

Boy этот кодвыглядит ужасно знакомым!И если позже я обнаружу, что было бы неплохо иметь вариант, который может хранить String s, я снова оставляю копирование и вставку точно такого же кода и настройку точно таких же мест, которые являются специфическими для содержимого типа.Разве не было бы неплохо, если бы был способ раз и навсегда создать связанный список, который мог бы содержать элементы любого отдельного типа, и функцию длины, которая работала бы равномерно, независимо от того, какие элементы у нее были?В конце концов, наши функции длины даже не заботились о значениях элементов.В 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

The forall говорит, что эта функция для всех вариантов связанных списков - связанных списков Int s, связанных списков Float s, связанных списков String s, связанных списков функций, которые принимают FibbledyGibbets и возвращают связанные спискикортежи Grazbars и WonkyNobbers, ...

Как мило!Теперь вместо отдельных типов IntLinkedList и FloatLinkedList мы можем просто использовать LinkedList Int и LinkedList Float для этого, а length_LinkedList, реализованный один раз, работает для обоих.

...