没有约束的GADT(或存在)是否可以编译为无类型的普通ADT?

lef*_*out 5 performance haskell existential-type gadt

假设我有一些ADT,比如

data Foo = Foo !Int
         | Bar (Int->Int) Foo
Run Code Online (Sandbox Code Playgroud)

现在说我要强加一些额外的类型安全,摆脱"魔数类型":

{-# LANGUAGE GADTs #-}

newtype Intey a = Intey { getIntey :: Int }

data Foo' a where
   Foo :: !(Intey a) -> Foo' a
   Bar :: (Intey a -> Intey b) -> Foo' a -> Foo' b
Run Code Online (Sandbox Code Playgroud)

因为b它只是构造函数中的一个幻像参数,没有约束或其他任何东西,它基本上没有意义 - 除了类型检查器.因此可以编译成相同的Foo,没有任何性能等成本吗?

GS *_*ica 7

你需要看看核心是绝对肯定的,但总的来说:

  • newtype与底层类型相比没有运行时成本.然而,类似的东西map getIntey仍然会无所事事.

  • 类型和类型参数本身在编译期间被擦除,因此也应该没有运行时成本 - 这是静态类型的优点之一.只有在使用类型类时才可以传递运行时值.

因此,在大多数情况下,您可以期望相同的性能,但您可能需要对列表等容器上的操作稍微小心.

如果你将自己限制在GHC 7.8,那么新的强制函数也可以帮助你.