2

次の型とクラスの定義を使用すると、以下を作成するときになぜエラーが発生するのかわかりませんinstance

異種の値のマップを保持するためにMyMapが必要です。

{-# LANGUAGE ExistentialQuantification #-}
module Scratch.SO_ExtistentialTypes where

import Data.Map

type MyMap a = Map String a

class MyClass c where 
    getMyMap :: forall a. c -> MyMap a

data MyData = forall a. MyData {
    myMap ::  MyMap a
}

instance MyClass MyData where
    getMyMap = myMap -- <= ERROR
4

1 に答える 1

9

一つには、forallここは不要です:

class MyClass c where 
    getMyMap :: forall a. c -> MyMap a

明示的なバインディングのない型変数は、最も外側のレベルで全称記号化されるため、これはちょうど。とまったく同じc -> MyMap aです。

それを超えて、全称記号型は確かに存在記号型と一致しません。タイプはgetMyMap、タイプの値が与えられると、タイプの可能な任意の選択に対してcタイプの値を生成することを示します。一方、アクセサは、typeの値が与えられると、特定の未知のタイプのtypeの値を生成すると言います。MyMap aamyMapMyDataMyMap aa

ラップされていない存在型を単独で浮かび上がらせることはできません(これにはにexists対応する数量詞が必要です)。したがって、有効な実装であるようなforall型を書き直す方法はありません。getMyMapmyMap

存在型を持つものでできることは、存在記号を非表示にする別のデータ型にラップバックするか、全称記号型の引数を持つ関数に渡すことだけです。たとえば、実存型lengthのリスト[a]で使用できます。a

あなたの場合、の値はMap他の構造や制約のない実存型であるため、ほとんど役に立たず、そうである可能性もあります()

于 2012-10-26T14:20:18.067 に答える