Каков эффект синонимов типа на экземплярах классов типа? Что делает прагму TypeSynonymInstances в GHC, делают?

Я читаю реальный мир Haskell Pg 151, и я уставился на следующий отрывок больше часа:

Вспомните, что Строка является синонимом для [Символа], который в свою очередь является типом, где Символом заменяют параметр типа a. Согласно правилам 98 Haskell, нам не разрешают предоставить тип вместо параметра типа, когда мы пишем экземпляр. Другими словами, это было бы законно, чтобы мы записали экземпляр для, но не для [Символа]. 16 комментариев 5335

Это просто не впитывается. Уставившись (свободный не ограбленный) копия главы 6 RWH, я вижу много других людей, действительно страдает с этим. Я все еще не понимаю это из комментариев...

Во-первых, все об этом смущает меня, поэтому, если Вы чувствуете, что можно объяснить что-либо об этом проходе, или TypeSynonymInstances сделайте.

Вот моя проблема:

  • Int конструктор данных
  • String конструктор данных, И введите синоним

Теперь я не могу ответить на эти вопросы:

  1. Почему синоним типа устранил бы создание типа член класса типа (я смотрю по некоторым причинам, который, вероятно, касается компиляции или реализации синонима типа)?
  2. Почему сделал разработчиков языка, не хотят этот синтаксис (я прошу обоснование не у обширной теории или unicode математических символов).
  3. Я вижу эту строку "тип, где Символом заменяют параметр типа", и я хочу знать, почему я не могу заменить им это "тип a, где Интервалом заменяют параметр типа a".

Спасибо!

17
задан Guy Coder 15 December 2013 в 14:34
поделиться

3 ответа

Я думаю, что частично проблема заключается в том, что действуют два, в основном не связанных, ограничения:

  • Отсутствие экземпляров синонимов типа означает, что экземплярами могут быть только объекты, объявленные с помощью data или newtype , но не type . Это запрещает String , но не [Char] .
  • Отсутствие гибких экземпляров означает, что экземпляры могут упоминать только один тип, который не является переменной, и только этот тип может использоваться в качестве конструктора типа. Это запрещает Может быть Int и f Int , но не Может быть .

Вот что GHCi говорит о Int , Char и String :

data Char = GHC.Types.C# GHC.Prim.Char#
data Int = GHC.Types.I# GHC.Prim.Int#
type String = [Char]

Int и Char оба простые типы без параметров типа переменных; здесь нет конструктора типов, поэтому вы можете свободно создавать экземпляры с ними.

Строка, однако, не работает на обоих счетах . Это недопустимый синоним типа, а также конструктор типа , применяемый к не-переменной , а именно конструктор типа списка, применяемый к Char.

Для сравнения обратите внимание, что [a] , Возможно a и Либо ab все допустимы в экземплярах, но [Int] , Может быть [a] и Любая строка a запрещены; надеюсь, теперь вы понимаете, почему.

Что касается ваших прямых вопросов, я не знаю, каковы исходные мотивы для разработки языка таким образом, и я никоим образом не квалифицирован, чтобы делать авторитетные заявления о «лучших практиках», кроме моего личного программирования. Я без колебаний использую эти прагмы:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}

Вы всегда можете посмотреть пакеты, в которых используются прагмы . Гибкие экземпляры, кажется, действительно используются довольно часто и из «респектабельных» пакетов (например, есть пара совпадений в исходном коде для Parsec).

27
ответ дан 30 November 2019 в 11:37
поделиться

int и string - это типы, а не ограничители данных. Строка бывает псевдонимами для [CHAR], которая также может быть написана списком Char. Конструктор данных - это что-то вроде всего, поэтому только 3 - это значение типа, может быть, INT. Тип синонимных экземпляров объясняется здесь:

http://hackage.haskell.org/trac/haskell-prime/wiki/typesynyminstances

0
ответ дан 30 November 2019 в 11:37
поделиться

На самом деле, ни Int, ни String не являются конструкторами данных. То есть их нельзя использовать для создания значения

> (Int 42, String "bob")
<interactive>:1:1: Not in scope: data constructor `Int'
<interactive>:1:9: Not in scope: data constructor `String'

Int, называющего новый, отличный от других, алгебраический тип данных. String является "тип-синонимом", или псевдонимом, для уже существующего типа: [Char]. Проблема в том, что Haskell 98 говорит, что нельзя использовать синоним типа в объявлении экземпляра.

Я не могу сказать, почему авторы отчета Haskell 98 решили ограничить синонимы типа в этом случае. На них существует довольно много ограничений. Например, они не могут быть частично применены (если они принимают аргументы типов). Я думаю, что подсказка приходит в конце §4.2.2:

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

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

Что касается вашего последнего вопроса, то я считаю, что объяснение объединяет две вещи: 1) Строка является синонимом типа для [Char], что в свою очередь является специализацией более общего типа [a] и 2) что даже без синонима [Char] не может быть использовано в голову экземпляра.

Эта вторая проблема не имеет ничего общего с синонимами типов, но в головах экземпляров должны быть все параметры типа для конструктора типов - это переменные, а не конкретные типы. То есть вы не можете определить отдельные экземпляры для [Int] и [Char] для какого-то класса, вы можете определить только экземпляры [a]. (Помните, что несмотря на удобный синтаксис, [] является конструктором типов, а внутри - параметром типа.)

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

Наконец, я видел, что оба расширения включены в довольно большом количестве кода, но, возможно, кто-то с большим опытом работы с Хаскеллом может взвесить, являются ли они "лучшими практиками" или нет.

10
ответ дан 30 November 2019 в 11:37
поделиться
Другие вопросы по тегам:

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