存在类型。编写一个异类地图的类的实例 [英] Existential Types. Writing the instance of a class for an heterogeneous map

查看:101
本文介绍了存在类型。编写一个异类地图的类的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下类型和类定义,我不明白为什么我在下面创建实例时遇到错误。


$ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆