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

时间:2011-05-04 21:31:13

标签: haskell polymorphism ghc existential-type newtype

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

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

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

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

2 个答案:

答案 0 :(得分: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

E.g。

*Main> main
"foo"
7
'x'

逻辑上,你需要在某处分配的字典(或标签)。如果你删除了构造函数,这没有意义。

注意:你不能像现在所暗示的那样打开函数,也不能打开多态字段。


  

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

删除-XGADT有助于我思考:

{-# 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被暴露,则opaque类型变量将被转义。

答案 1 :(得分:3)

我认为没有任何理由不能使其工作,但也许ghc有一些内部代表问题。