Есть ли способ определить экзистенциально количественно новый тип в GHC Haskell? - PullRequest
18 голосов
/ 05 мая 2011

Возможно ли в (GHC) Haskell определить экзистенциально количественно определенный новый тип? Я понимаю, что если задействованы классы типов, это невозможно сделать в реализации, передающей словарь, но для моих целей классы типов не нужны. То, что я действительно хотел бы определить, это:

newtype Key t where Key :: t a -> Key t

Но GHC, похоже, это не нравится. В настоящее время я использую data Key t where Key :: !(t a) -> Key t. Есть ли способ (возможно, просто с помощью -funbox-strict-fields?) Определить тип с той же семантикой и накладными расходами, что и у версии нового типа выше? Насколько я понимаю, даже при распакованных строгих полях все равно будет дополнительное слово тега, хотя я могу быть совершенно не прав.

Это не то, что вызывает у меня какие-либо заметные проблемы с производительностью. Меня просто удивило, что новый тип был запрещен. Я, естественно, любопытный человек, поэтому я не могу не задаться вопросом, компилируется ли моя версия с тем же представлением или может быть определен любой эквивалентный тип, который был бы.

Ответы [ 2 ]

6 голосов
/ 05 мая 2011

Нет, согласно GHC:

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

Однако, data просто отлично:

{-# LANGUAGE ExistentialQuantification #-}

data E = forall a. Show a => E a

test = [ E "foo"
       , E (7 :: Int)
       , E 'x'
       ]

main = mapM_ (\(E e) -> print e) test

Например,

*Main> main
"foo"
7
'x'

Логически вам нужно нужен словарь (или тег), размещенный где-то.И это не имеет смысла, если вы удаляете конструктор.

Примечание : Вы не можете распаковать функции, как вы, похоже, намекаете, или полиморфные поля.


Есть ли способ (возможно, просто с помощью -funbox-strict-fields?) Определить тип с той же семантикой и служебной информацией, что и у версии нового типа, описанной выше?

Удаление -XGADTs помогает мне подумать об этом:

{-# LANGUAGE ExistentialQuantification #-}

data Key t = forall a. Key !(t a)

Как и в Key (Just 'x') :: Key Maybe

enter image description here

Итак, вы хотите гарантировать, что конструктор Key будет удален.

Вот код в GHC для проверки типов на newtype:

-- Checks for the data constructor of a newtype
checkNewDataCon con
  = do  { checkTc (isSingleton arg_tys) (newtypeFieldErr con (length arg_tys))
        -- One argument
    ; checkTc (null eq_spec) (newtypePredError con)
        -- Return type is (T a b c)
    ; checkTc (null ex_tvs && null eq_theta && null dict_theta) (newtypeExError con)
        -- No existentials
    ; checkTc (not (any isBanged (dataConStrictMarks con)))
          (newtypeStrictError con)
        -- No strictness

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

Единственное, о чем я могу думать, это то, что, как и при доступе к записям для экзистенциалов, непрозрачная переменная типа будет экранирована, если newtype выставлен.

3 голосов
/ 05 мая 2011

Я не вижу причин, по которым его нельзя было заставить работать, но, возможно, у ghc есть некоторые внутренние проблемы с представлением.

...