存在类型。编写一个异类地图的类的实例 [英] Existential Types. Writing the instance of a class for an heterogeneous map
问题描述
使用以下类型和类定义,我不明白为什么我在下面创建实例
时遇到错误。
$ b $
{ - #LANGUAGE ExistentialQuantification# - }
我需要MyMap来保存异构值的映射。 b模块Scratch.SO_ExtistentialTypes其中
导入Data.Map
类型MyMap a =映射字符串a
类MyClass c其中
getMyMap :: forall a。 c - > MyMap a
data MyData = forall a。 MyData {
myMap :: MyMap a
}
实例MyClass MyData其中
getMyMap = myMap - < = ERROR
首先, forall
这里是多余的:
class MyClass c其中
getMyMap :: forall a。 c - > MyMap a
没有显式绑定的类型变量在最外层是普遍量化的,所以这就是同样只是 c - > MyMap a
。
除此之外,普遍量化类型当然不会与存在量化类型相匹配。 getMyMap
的类型表示,给定 c
类型的值,它将生成一个类型为 MyMap a
,用于 a
类型的任何可能的选择。另一方面,访问器 myMap
说,给定一个类型为 MyData
的值,它将产生一个值请为 a
。
不可能有自解释的存在类型自己浮动(这将需要一个存在
量词对应于 forall
),因此无法重写 getMyMap
的类型,因此 myMap
是有效的实现。
所有你可以对具有存在类型的东西做的事情都是用另一种隐藏存在量词的数据类型来包装它,或者把它赋予一个具有普遍量化参数的函数类型。例如,您可以使用长度
在 [a]
列表上使用 a
存在类型。
在你的情况下, Map
的值的存在类型为no其他结构或约束,所以它们几乎没用,并且可能是()
。
Using the following type and class definitions, I do not understand why I get and error when creating the instance
below.
I need MyMap to hold a map of heterogeneous values.
{-# 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
For one thing, the forall
here is superfluous:
class MyClass c where
getMyMap :: forall a. c -> MyMap a
Type variables with no explicit binding are universally quantified at the outermost level, so this is exactly the same as just c -> MyMap a
.
Beyond that, a universally quantified type is certainly not going to match an existentially quantified type. The type of getMyMap
says that, given a value of type c
, it will produce a value of type MyMap a
for any possible choice of type a
. On the other hand, the accessor myMap
says that, given a value of type MyData
, it will produce a value of type MyMap a
for some specific but unknown type a
.
It's not possible to have unwrapped existential types floating around by themselves (this would require an exists
quantifier corresponding to forall
), so there's no way to rewrite the type of getMyMap
such that myMap
is a valid implementation.
All you can do with something having an existential type is wrap it back up in another data type that hides the existential quantifier, or give it to a function that has an argument with a universally quantified type. For example, you can use length
on a list [a]
with a
an existential type.
In your case, the values of the Map
have existential type with no other structure or constraints, so they're pretty much useless and might as well be ()
.
这篇关于存在类型。编写一个异类地图的类的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!