是否有“newtype T = MkT(T - > T)”的用例?

时间:2012-12-04 03:42:16

标签: haskell

Sulzmann,Chakravarty和Peyton Jones撰写的论文"System F with Type Equality Coercions"通过以下示例说明了Haskell的newtype到System FC的翻译:

newtype T = MkT (T -> T)

根据我的理解,禁止unsafePerformIO,由于参数化原因,此类型的唯一可能值为MkT idMkT undefined。如果这个(或类似的)定义有一些实际用途,我很好奇。

1 个答案:

答案 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)

类型TUntyped 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根本不是一种有用的类型,但在另一种意义上,是所有中最有用的类型。