Подтвердить что ты не робот

Почему в GHC Haskell нет экзистенциально квантифицированных переменных типа

Существуют универсально квантифицированные переменные типа, и существуют типы данных с количественной оценкой по существу. Однако, несмотря на то, что люди дают псевдокод формы exists a. Int -> a, чтобы иногда помогать объяснять понятия, это не похоже на расширение компилятора, в котором есть какой-то реальный интерес. Это просто "нет большого значения при добавлении этого", (потому что это кажется мне ценным), или есть проблема, такая как неразрешимость, которая делает ее поистине невозможной.

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

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

data Person a = Person
  { age: Int
  , height: Double
  , weight: Int
  , name: a
  }

Итак, мы выбираем параметрize over a, который является соглашением об именах (я знаю, что в этом примере, вероятно, имеет смысл сделать ADT NamingConvention с соответствующими конструкторами данных для американской "первой, средней, последней", "испаноязычное" имя, отцовское имя, материнское имя и т.д. Но пока, просто пойдите с этим).

Итак, есть несколько функций, которые мы видим, в основном игнорируем тип, с которым параметризуется Person. Примеры:

age :: Person a -> Int
height :: Person a -> Double
weight :: Person a -> Int

И любая функция, построенная поверх них, аналогичным образом игнорирует тип a. Например:

atRiskForDiabetes :: Person a -> Bool
atRiskForDiabetes p = age p + weight p > 200
--Clearly, I am not actually a doctor

Теперь, если у нас есть гетерогенный список людей (типа [exists a. Person a]), мы хотели бы иметь возможность отображать некоторые из наших функций над списком. Конечно, есть некоторые бесполезные способы отображения:

heteroList :: [exists a. Person a]
heteroList = [Person 20 30.0 170 "Bob Jones", Person 50 32.0 140 3451115332]
extractedNames = map name heteroList

В этом примере extractedNames, конечно, бесполезен, поскольку имеет тип [exists a. a]. Однако, если мы используем другие наши функции:

totalWeight :: [exists a. Person a] -> Int
totalWeight = sum . map age

numberAtRisk :: [exists a. Person a] -> Int
numberAtRisk = length . filter id . map atRiskForDiabetes

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

data SomePerson = forall a. SomePerson (Person a) --fixed, thanks viorior

Но теперь, как мы можем использовать age и atRiskForDiabetes? Мы не можем. Я думаю, что вам нужно будет сделать что-то вроде этого:

someAge :: SomePerson -> Int
someAge (SomePerson p) = age p

Который действительно хромой, потому что вам нужно переписать все ваши комбинаторы для нового типа. Это становится еще хуже, если вы хотите сделать это с типом данных, параметризованным по нескольким переменным типа. Представьте себе следующее:

somewhatHeteroPipeList :: forall a b. [exists c d. Pipe a b c d]

Я не буду объяснять эту мысль дальше, но просто обратите внимание, что вы переписываете много комбинаторов, чтобы сделать что-то подобное, используя только экзистенциальные типы данных.

Сказав это, я надеюсь, что я мягко убеждаю, что это может быть полезно. Если это не кажется полезным (или если пример кажется слишком изобретенным), не стесняйтесь, дайте мне знать. Кроме того, поскольку я в первую очередь программист и не имею подготовки по теории типов, мне немного сложно понять, как использовать теорему Сколема (как размещено viorior) здесь. Если бы кто-нибудь мог показать мне, как применить его к примеру Person a, который я дал, я был бы очень благодарен. Спасибо.

4b9b3361

Ответ 1

Это не нужно.

По теореме Сколема мы могли бы преобразовать квантор существования в универсальный квантор с более высокими типами рангов:

(∃b. F(b)) -> Int   <===>  ∀b. (F(b) -> Int)

Каждый экзистенциально квантованный тип ранга n + 1 может быть закодирован как универсально квантованный тип ранга n

Ответ 2

В GHC присутствуют экзистенциально квантифицированные типы , поэтому вопрос основан на ложном предположении.