假设我有一些ADT,比如 data Foo = Foo !Int | Bar (Int-Int) Foo 现在说我要强加一些额外的类型安全,摆脱“魔数类型”: {-# LANGUAGE GADTs #-}newtype Intey a = Intey { getIntey :: Int }data Foo' a where Foo :: !(In
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相同,没有任何性能等成本吗?
你需要看看核心是绝对肯定的,但总的来说:>与基础类型相比,newtype没有运行时成本.然而,像map getIntey这样的东西仍会遍历列表无所事事.
>类型和类型参数本身在编译期间被擦除,因此也应该没有运行时成本 – 这是静态类型的优点之一.只有在使用类型类时才可以传递运行时值.
因此,在大多数情况下,您可以期望相同的性能,但您可能需要对列表等容器上的操作稍微小心.
如果你限制自己使用GHC 7.8,那么新的coerce功能也可以帮助你.