Почему Haskell не доходит выводить typeclasses типа данных в функциональных подписях?

Во-первых, этот вопрос не на 100% характерен для Haskell, не стесняйтесь комментировать общий дизайн typeclasses, интерфейсов и типов.

Я читаю LYAH - создающие типы и typeclasses, следующее является проходом, для получения дополнительной информации о котором я смотрю:

Data (Ord k) => Map k v = ...  

Однако это - очень сильная конвенция в Haskell никогда не добавить typeclass ограничения в объявлениях данных. Почему? Ну, потому что мы не извлекаем выгоду много, но мы заканчиваем тем, что писали больше ограничений класса, даже когда нам не нужны они. Если мы помещаем или не помещаем Порядок k ограничение в объявлении данных для Карты k v, мы оказываемся перед необходимостью помещать ограничение в функции, которые предполагают, что ключи в карте могут быть заказаны. Но если мы не помещаем ограничение в объявление данных, мы не должны помещать (Порядок k) => в описаниях типа функций, которые не заботятся, могут ли ключи быть заказаны или нет. Примером такой функции является toList, который просто берет отображение и преобразовывает его в ассоциативный список. Его подпись типа является toList:: Карта k-> [(k, a)]. Если бы Карта k v имела ограничение типа в своем объявлении данных, то тип для toList должен был бы быть toList:: (Порядок k) => Карта k-> [(k, a)], даже при том, что функция не делает никакого сравнения ключей согласно порядку.

Это сначала, кажется логичным - но не является там позитивным аспектом к присоединению typeclass к типу? Если typeclass является поведением типа, то, почему поведение должно быть определено при помощи типа (через функции) а не самого типа? Я предполагаю, что существует некоторое метапрограммирование, которое могло использовать его, и это - конечно, хорошая и описательная документация кода. С другой стороны это было бы хорошей идеей на других языках? Это было бы идеально для определения интерфейса, которому объект должен соответствовать на методе, таком, что, если метод не используется вызывающей стороной, объект не должен соответствовать интерфейсу? Кроме того, почему Haskell не может вывести что функция с помощью типа Foo, должен вытянуть в typeclass ограничениях, определенных в типе Fooобъявление? Существует ли прагма для включения этого?

В первый раз, когда я считал его, это колдовало, "это - взлом (или обходное решение) ответ". На втором чтении с некоторой мыслью это звучало умным. На третьем чтении, таща compairison к миру OO, это походило на взлом снова.

Так я здесь

15
задан Evan Carroll 31 January 2010 в 02:38
поделиться

4 ответа

Возможно Map K V не был лучшим примером для иллюстрации точки. Учитывая определение карты , даже если есть некоторые функции, которые не понадобится (ORD K) , не существует возможного способа построить карту без этого.

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

Например, Data.List содержит много функций, требующих (эквалайзер A) , но из списков курса идеально полезны без этого ограничения.

10
ответ дан 1 December 2019 в 02:55
поделиться

Краткий ответ: Haskell делает это, потому что это то, как написано на основе языка.

Долгий ответ включает в себя цитату из раздела языка языка в :

Любой тип данных, который можно объявить в стандартном синтаксисе HASKELL-98, также можно объявить с помощью синтаксиса стилей GADT. Выбор в значительной степени стилистично, но декларации в стиле GADT различаются в одном важном отношении: они обрабатывают ограничения классов на конструкторах данных по-разному. В частности, если конструктор дан контекст класса типа, этот контекст предоставляется доступным по сравнению с шаблоном. Например:

data Set a where
    MkSet :: Eq a => [a] -> Set a

(...)

Все это поведение контрастирует с своеобразной обработкой контекстов HASKELL 98 на декларации типа данных (, раздел 4.2.1 отчета HASKELL 98 ). В Haskell 98 определение

data Eq a => Set' a = MkSet' [a]

дает mkset 'одинаковый тип, что и mkset выше. Но вместо того, чтобы сделать доступным (уравнение а) ограничением, сопоставление шаблона на Mkset 'требует ограничения (EQ a)! GHC верно реализует это поведение, нечетное, хотя оно есть. Но для деклараций стилей GADT поведение ГХК гораздо полезнее, а также гораздо более интуитивно.

8
ответ дан 1 December 2019 в 02:55
поделиться
121 --- 4746360

Основная причина, повод избежать ограничения типов в декларациях данных, заключается в том, что они не достигают абсолютно ничего; Фактически, я считаю, что GHC относится к такому контексту классов как «глупый контекст». Причина этого состоит в том, что словарь класса не передается со значениями типа данных, поэтому вы должны добавить его в каждую функцию, работающую на значениях в любом случае.

Как способ «принуждать» ограничения TypeClass на функции, работающие на типе данных, он также ничего не выполняет; Функции, как правило, должны быть как можно более полиморфными, поэтому зачем заставить ограничение на вещи, которые не нуждаются в этом?

На данный момент вы можете подумать, что должно быть возможно изменить семантику объявлений, чтобы нести словарь вокруг со значениями. На самом деле, кажется, это весь точка ГАДТ ; Например, вы можете сделать:

data Foo a where { Foo :: (Eq a) => a -> Foo a }
eqfoo :: Foo t -> Foo t -> Bool
eqfoo (Foo a) (Foo b) = a == b

Обратите внимание, что тип EQFOO не требует ограничения EQ, так как оно «переносится» сам типом данных FO.

6
ответ дан 1 December 2019 в 02:55
поделиться

Я хотел бы указать, что если вы беспокоитесь, что можно построить объект, который может построить объект, который может построить Требуется ограничения для его операций, но не для его создания, скажем, MKFOO, вы всегда можете искусственно поместить ограничение в функцию Mkfoo, чтобы обеспечить использование типеклассий людей, которые используют код. Идея также распространяется на функции типа Non Mkfoo, которые работают на FOO. Затем при определении модуля не экспортируйте ничего, что не придерживается ограничений.

Хотя я должен признать, я не вижу никакого использования для этого.

1
ответ дан 1 December 2019 в 02:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: