DatatypeContexts устарели в последней версии GHC: почему?

Я просто занимался разработкой на Haskell и перекомпилировал старый код в новой версии GHC:

The Glorious Glasgow Haskell Compilation System, version 7.2.1

И когда я это сделал, я получил следующую ошибку:

Предупреждение: -XDatatypeContexts устарел: это считалось ошибочным и было удалено из языка Haskell.

Это появляется, когда у вас есть код в следующем формате:

data Ord a => MyType a
    = ConstructorOne a
    | ConstructorTwo a a

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


person Robert Massaioli    schedule 15.09.2011    source источник
comment
Просто удалите контекст, и ваш код все равно будет работать.   -  person augustss    schedule 16.09.2011
comment
Если вы получаете соответствующую ошибку при попытке cabal install <package>, попробуйте cabal install --ghc-option '-XDataTypeContexts' <package>.   -  person ntc2    schedule 23.05.2012
comment
@ntc2 В качестве предложенного ответа, возможно, команда должна содержать -XDatatypeContexts без строчной буквы t.   -  person Ludovic Kuty    schedule 03.11.2018


Ответы (2)


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

«Замена», которая на самом деле работает по-другому и отслеживает известные вам контексты, заключается в вместо этого используйте объявления в стиле GADT:

data MyType a where
    ConstructorOne :: Ord a => a -> MyType a
    ConstructorTwo :: Ord a => a -> a -> MyType a

GADT в целом более гибкие и во многих других отношениях, но в этом конкретном случае происходит следующее: создание значения требует ограничения Ord, которое затем переносится вместе со значением, и сопоставления шаблонов на конструктор вытаскивает его обратно. Таким образом, вам даже не нужен контекст для функций, использующих его, потому что вы знаете, что, ожидая чего-то типа MyType a, вы получите с ним ограничение Ord a.

person C. A. McCann    schedule 15.09.2011
comment
Последнее предложение кажется немного неясным: то, что вы извлекаете из конструктора GADT, является не ограничением, а экземплярами, удовлетворяющими ограничению. - person dfeuer; 26.06.2015
comment
Но если конструкторов слишком много, не будет ли слишком многословно повторять Ord a для каждого? - person fakedrake; 05.10.2016
comment
@fakedrake Я имею в виду, что это не должно появляться часто. Вы почти всегда не хотите ограничивать свои типы таким образом. Одним из примеров того, почему это делает невозможным сделать ваш тип Functor, Foldable, Traversable, Applicative, Monad, Alternative, MonadPlus, Arrow и так далее. - person semicolon; 25.02.2017
comment
GADT очень хороши, потому что в некоторых случаях у меня могут быть более ограниченные конструкторы, и я обнаружил, что это полезно в таких случаях. Спасибо за ответ. - person Paul Stelian; 03.11.2020

В общем, вам по-прежнему нужно добавлять ограничение Ord a к любой функции, которая использует ваш тип MyType, и поэтому оно не так полезно, как может показаться. Для получения дополнительной информации о том, почему они были удалены, см. http://hackage.haskell.org/trac/haskell-prime/wiki/NoDatatypeContexts

person ivanm    schedule 15.09.2011