我对新类型的理解是它们是由GHC编制的。然而,这不可能是整个故事,因为幻影类型可以保存信息。
来自here:
你可以将[a type]包装在newtype中,它将被视为与type-checker不同,但在运行时相同。然后,您可以使用各种深度技巧,如幻像或递归类型,而无需担心GHC随机填充字节桶。
例如,假设一个表示算术模q的新类型:
newtype Zq q = Zq Int
class Modulus q where
getModulus :: q -> Int
addZq :: (Modulus q) => Zq q -> Zq q -> Zq q
addZq (Zq a) (Zq b) = Zq $ (a+b) `mod` (getModulus (undefined :: q))
addZq
无法编译为
addZq :: Int -> Int -> Int
所以编译出来的newtype是什么意思,幻像类型信息存储在哪里?
答案 0 :(得分:14)
要记住的是,你没有“编译”到Haskell;你可以编译成其他一些更明确的语言 - 在GHC的情况下,下一个众所周知的下台是核心。虽然您无法将addZq
编译为Core中的Int -> Int -> Int
类型,但可以将其编译为可能写为Modulus q => Int -> Int -> Int
的类型的内容。在这种更明确的语言中,=>
具有与Haskell不同的含义;在这种语言中,c => t
是一个函数的类型,它为声明c
获取证据(在本例中为类字典),并生成t
类型的东西。因此Modulus q => Int -> Int -> Int
与(q -> Int) -> Int -> Int -> Int
大致相同,addZq
当然 可以获得该类型,即使在Haskell中也是如此。
答案 1 :(得分:4)
如果说GHC编译出newtypes,这意味着只表示运行时行为。具体来说,保证它们不会比没有newtype
的相同代码慢。但是他们仍然在整个编译过程中继续传递类型信息,包括用作幻像类型时。
换句话说,newtype只是编译时信息,这足以让幻像类型工作。