使用以下类型和类定义,我不明白为什么在下面创建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
答案 0 :(得分:9)
首先,这里的forall
是多余的:
class MyClass c where
getMyMap :: forall a. c -> MyMap a
没有显式绑定的类型变量在最外层被普遍量化,因此这与c -> MyMap a
完全相同。
除此之外,普遍量化的类型肯定不会与存在量化类型相匹配。 getMyMap
的类型表示,如果类型为c
,则会为类型MyMap a
的任何可能选择生成类型a
的值。另一方面,访问者myMap
表示,如果类型为MyData
,则会为某些特定但未知类型MyMap a
生成类型a
的值。
不可能让自己包含的展开存在类型(这需要exists
对应于forall
的量词),所以没有办法重写getMyMap
这样的类型myMap
是一个有效的实现。
对于具有存在类型的东西,你可以做的就是将它包装回另一种隐藏存在量词的数据类型,或者将它赋予一个具有普遍量化类型的参数的函数。例如,您可以在列表length
上使用[a]
,a
为存在类型。
在您的情况下,Map
的值具有存在类型,没有其他结构或约束,因此它们几乎没用,也可能是()
。