在我尝试理解存在类型时,我读到 Church 编码以及 Rank-N 类型扩展足以在没有存在量化的情况下在 Haskell 中对它们进行编码。我发现了这个简单的例子:
type Obj = forall y. (forall x. (Show x) => x -> y) -> y
obj :: Obj
obj f = f "hello"
app :: Obj -> String
app obj = obj (\x -> show x)
在 Haskell Wiki 中,我偶然发现了以下基于存在类型的异构列表示例:
data Obj = forall a. (Show a) => Obj a
xs :: [Obj]
xs = [Obj 1, Obj "foo", Obj 'c']
doShow :: [Obj] -> String
doShow [] = ""
doShow ((Obj x):xs) = show x ++ doShow xs
现在我尝试用 Church 来表达这个实现,但由于非法多态类型错误而失败:
type Obj = forall y. (forall x. (Show x) => x -> y) -> y
obj1 :: Obj
obj1 f = f 1
obj2 :: Obj
obj2 f = f "foo"
obj3 :: Obj
obj3 f = f 'c'
xs :: [Obj]
xs = [obj1, obj2, obj3]
doShow :: [Obj] -> String
doShow [] = ""
doShow (obj:xs) = obj (\x -> show x ++ doShow xs)
我想这个翻译很简略,完全是错误的。存在类型可以用 Church/Rank-N 编码吗?它是如何正确完成的?