Нет, согласно 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](https://i.stack.imgur.com/okb1j.png)
Итак, вы хотите гарантировать, что конструктор 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
выставлен.