奇怪的存在类型

时间:2012-12-29 00:05:14

标签: haskell existential-type

http://www.iai.uni-bonn.de/~jv/mpc08.pdf - 在本文中,我无法理解以下声明:

instance TreeLike CTree where
...
abs :: CTree a -> Tree a
improve :: (forall m. TreeLike m => m a) -> Tree a
improve m = abs m
  1. 有什么区别(forall m.TreeLike m => m a)带来了(我认为TreeLike m => m a就足够了)

  2. 为什么它允许abs在这里,如果m in m a可以是任何TreeLike,而不仅仅是CTree?

2 个答案:

答案 0 :(得分:9)

这是一种排名2型,而不是存在型。该类型的含义是improve的参数必须是多态的。您不能将Ctree a类型的值(例如)传递给improve。它在类型构造函数中根本不具体。它在类型构造函数中必须是多态的,并且类型构造函数实现Treelike类的约束。

对于你的第二个问题,这允许improve的实现选择它想要的m的任何类型 - 它是实现的选择,并且类型系统对调用者隐藏它。在这种情况下,实施恰好为Ctree选择m。那完全没问题。诀窍是improve的调用者无法在任何地方使用该信息。

这具有实际结果,即不能使用类型的细节构造值 - 它必须使用Treelike类中的函数来构造它。但是实现可以选择一种特定的类型来使其工作,允许它在内部使用表示的细节。

答案 1 :(得分:4)

m是否可以是“任何TreeLike”取决于您的观点。

从实施improve的角度来看,这是真的 - m可以是任何TreeLike,因此它会选择一个方便的,并使用abs

从论证m的角度来看 - 也就是说,任何将improve应用于某些论证的观点,恰恰相反的是:m实际上必须能任何TreeLike,而不是我们选择的任何一个(5 :: forall a. Num a => a)

将此与数字文字的类型进行比较 - 类似于Num意味着它是我们想要的任何(forall a. Num a => a)实例,但是如果函数需要类型Num的参数它想要的东西可以是选择的任何5个实例。所以我们可以给它一个多态的Integer但不是(forall m. TreeLike m => m a) -> Tree a 5。

在很多方面,您可以将多态类型视为函数将类型作为额外参数的含义,它告诉我们要为每个类型变量使用哪种特定类型。因此,要查看forall m. TreeLike m => m a -> Tree a(M -> M a) -> Tree a之间的区别,您可以将其视为M -> M a -> Tree a与{{1}}之类的内容。