有没有办法在GHC Haskell中定义一个存在量化的新类型?

mok*_*kus 18 polymorphism haskell existential-type ghc newtype

(GHC)Haskell是否有可能定义一个存在量化的新类型?我理解如果涉及类型类,则无法在字典传递实现中完成,但对于我的目的,不需要类型类.我真正想要定义的是:

newtype Key t where Key :: t a -> Key t
Run Code Online (Sandbox Code Playgroud)

但GHC似乎并不喜欢它.目前我正在使用data Key t where Key :: !(t a) -> Key t.有没有办法(也许只是使用-funbox-strict-fields?)来定义一个与上面的newtype版本具有相同语义和开销的类型?我的理解是,即使有严格的字段取消装箱,仍然会有一个额外的标签字,尽管我可能完全错了.

这不是导致我出现明显性能问题的原因.让我感到惊讶的是,不允许使用newtype.我是一个天生好奇的人,所以我不禁想知道我的版本是否被编译成相同的表示,或者是否可以定义任何等效类型.

Don*_*art 6

不,GHC表示:

newtype构造函数不能具有存在上下文

但是,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
Run Code Online (Sandbox Code Playgroud)

例如

*Main> main
"foo"
7
'x'
Run Code Online (Sandbox Code Playgroud)

从逻辑上讲,您确实需要在某处分配字典(或标记).如果你删除构造函数,这没有意义.

注意:您可以不打开unbox功能,因为您似乎在暗示,而不是多态字段.


有没有办法(也许只是使用-funbox-strict-fields?)来定义一个与上面的newtype版本具有相同语义和开销的类型?

删除-XGADTs有助于我思考:

{-# LANGUAGE ExistentialQuantification #-}

data Key t = forall a. Key !(t a)
Run Code Online (Sandbox Code Playgroud)

如, Key (Just 'x') :: Key Maybe

在此输入图像描述

所以你想保证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
Run Code Online (Sandbox Code Playgroud)

我们可以看到为什么!对表示没有任何影响,因为它包含多态组件,因此需要使用通用表示.并且没有提升newtype是没有意义的,也不是非单身的构造者.

我唯一能想到的是,就像存在的记录访问器一样,如果newtype暴露了opaque类型变量,它将会被转义.