Sulzmann,Chakravarty和Peyton Jones撰写的论文"System F with Type Equality Coercions"通过以下示例说明了Haskell的newtype
到System FC的翻译:
newtype T = MkT (T -> T)
根据我的理解,禁止unsafePerformIO
,由于参数化原因,此类型的唯一可能值为MkT id
和MkT undefined
。如果这个(或类似的)定义有一些实际用途,我很好奇。
答案 0 :(得分:20)
参数化是指具有变量的类型的值。 T
没有变量,因此参数不适用。事实上,T有很多居民
ap :: T -> T -> T
ap (MkT f) t = f t
idT :: T
idT = MkT id
constT :: T
constT = MkT $ \t -> MkT $ \_ -> t
axiom_sT :: T
axiom_sT = MkT $ \f -> MkT $ \g -> MkT $ \a -> (g `ap` a) `ap` (f `ap` a)
类型T
是Untyped Lambda Calculus的一种实现,是一种与图灵机相当的通用正式系统。上面的三个函数(加ap
)形成了SKI演算,一个等效的正式系统。
可以将任何Haskell数据类型编码为T
。考虑自然数的类型
data Nat = Zero | Succ Nat
我们可以将Nat
编码为T
church :: Nat -> T
church Zero = MkT $ \f -> MkT $ \x -> x
church (Succ n) = MkT $ \f -> MkT $ \x -> f `ap` (church n)
现在,你是部分正确的。在Haskell中没有办法写出这个的反函数(据我所知)。这真是一种耻辱。虽然您可以使用类型T -> IO Nat
编写一种伪逆。另外,我的理解是GHC优化器可能会死于递归newtypes
(如果我错了,请有人纠正我,因为我想回去使用它们。)
相反,类型
data T = MkT (T -> T) | Failed String
与
ap (MkT f) a = f a
ap (Failed s) _ = Failed s
是lambda演算,除了例外,可以完全可逆的方式使用。
总之,在某种意义上,T
根本不是一种有用的类型,但在另一种意义上,是所有中最有用的类型。