2

我对新类型的理解是它们是由 GHC 编译出来的。然而,这不可能是全部,因为幻像类型可以保存信息。

这里

您可以将 [a type] 包装在 newtype 中,它将被认为与类型检查器不同,但在运行时相同。然后,您可以使用各种深层技巧,例如幻像或递归类型,而不必担心 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 是在什么意义上编译出来的,幻像类型信息存储在哪里呢?

4

2 回答 2

14

要记住的是,您不会“编译”到 Haskell。你编译成其他更明确的语言——在 GHC 的情况下,下一个众所周知的步骤是核心。尽管你不能在 Core 中编译addZq成某种类型,但你可以将它编译成你可以写成. 在这种更明确的语言中,与 Haskell 中的含义不同;在这种语言中,是一个函数的类型,它为声明获取证据(在这种情况下是类字典)并产生类型的东西。So与 大致相同,并且当然可以给出该类型,即使在 Haskell 中也是如此。Int -> Int -> IntModulus q => Int -> Int -> Int=>c => tctModulus q => Int -> Int -> Int(q -> Int) -> Int -> Int -> IntaddZq

于 2013-11-08T16:36:50.330 回答
4

当说newtypes 是由GHC 编译出来时,这仅仅意味着运行时行为。具体来说,保证它们不会比没有newtype. 但是它们仍然在整个编译过程中携带类型信息,包括用作幻像类型时。

换句话说,新类型只是编译时信息,这足以让幻像类型工作。

于 2013-11-08T16:22:14.693 回答