4

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 => ma) がもたらす違い (ここでは TreeLike m => ma で十分だと思いました)

  2. ma の m が CTree だけでなく任意の TreeLike にできるのに、なぜここで abs を許可するのですか?

4

2 に答える 2

9

あれはランク2型であり、存在型ではない。その型が意味するのは、引数improveが多態的でなければならないということです。Ctree aタイプ(たとえば)の値を に渡すことはできませんimprove。型コンストラクターで具象化することはできません。Treelike型コンストラクターがクラスを実装するという制約付きで、型コンストラクター内で明示的にポリモーフィックである必要があります。

2番目の質問については、これにより、の実装で必要なimprove型を選択できます。これmは実装の選択であり、型システムによって呼び出し元から隠されています。この場合、実装はたまたま選択Ctreemます。それはまったく問題ありません。秘訣は、の呼び出し元がimproveその情報をどこでも使用できないことです。

これには、型の詳細を使用して値を構築できないという実際的な結果がありますTreelike。代わりに、クラス内の関数を使用して構築する必要があります。しかし、実装はそれが機能する特定のタイプを選択するようになり、表現の詳細を内部で使用できるようになります。

于 2012-12-29T00:14:57.003 に答える
4

m「任意の TreeLike」にできるかどうかは、視点によって異なります。

を実装するという観点からはimprove、それは真実mです。任意の を使用できるTreeLikeため、便利なものを選択して を使用しますabs

引数の観点、つまり、何らかの引数にm適用されるものの観点からは、むしろ反対のことが成り立ちます。実際には、選択した単一のものではなく、任意のimprovemTreeLike

これを数値リテラルの型と比較してください。このようなもの(5 :: forall a. Num a => a)は、それが任意のNumインスタンスであることを意味しますが、関数が型の引数を期待する場合、選択した任意のインスタンス(forall a. Num a => a)なり得るものを必要とします。したがって、ポリモーフィックを与えることはできますが、たとえば5 を与えることはできません。Num5Integer

多くの点で、ポリモーフィック型は、関数が追加の引数として型を取り、各型変数に使用する特定の型を伝えることを意味すると考えることができます。したがって、 と の違いを確認するには、(forall m. TreeLike m => m a) -> Tree avs.のforall m. TreeLike m => m a -> Tree aように読むことができます。(M -> M a) -> Tree aM -> M a -> Tree a

于 2012-12-29T00:15:22.540 に答える