幻像类型如何与newtype一起使用?

时间:2013-11-08 16:20:15

标签: haskell newtype phantom-types

我对新类型的理解是它们是由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是什么意思,幻像类型信息存储在哪里?

2 个答案:

答案 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只是编译时信息,这足以让幻像类型工作。