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.我是一个天生好奇的人,所以我不禁想知道我的版本是否被编译成相同的表示,或者是否可以定义任何等效类型.
不,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类型变量,它将会被转义.