6

假设我有一些 ADT,比如

data Foo = Foo !Int
         | Bar (Int->Int) Foo

现在说我想强加某种额外的类型安全,摆脱“幻数类型”:

{-# 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

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

4

1 回答 1

8

您需要查看核心以绝对确定,但总的来说:

  • newtype与底层类型相比,没有运行时成本。然而,类似的东西map getIntey仍然会遍历列表,什么都不做。

  • 类型和类型参数本身在编译期间会被删除,因此也应该没有运行时成本——这是静态类型的优点之一。只有当您使用类型类时,才能传递运行时值。

因此,在大多数情况下,您可以期待相同的性能,但您可能需要对容器(如列表)上的操作有点小心。

如果您将自己限制在 GHC 7.8,那么新的强制功能也可以帮助您。

于 2014-04-15T11:09:00.097 回答