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

没有显式绑定的类型变量在最外层被普遍量化,所以这与 just 完全相同c -> MyMap a

除此之外,普遍量化的类型肯定不会匹配存在量化的类型。的类型getMyMap表示,给定一个类型的值c,它将MyMap a为任何可能的类型选择产生一个类型的值a。另一方面,访问器myMap说,给定一个 type 的值MyData,它将MyMap a为一些特定但未知的 type生成一个 type 的值a

无法让展开的存在类型自行浮动(这将需要exists对应于 的量词forall),因此无法重写有效实现getMyMap的类型。myMap

对于具有存在类型的东西,您所能做的就是将其包装在另一个隐藏存在量词的数据类型中,或者将其提供给具有通用量化类型的参数的函数。例如,您可以在具有存在类型length的列表上使用。[a]a

在您的情况下,Map存在类型的值没有其他结构或约束,因此它们几乎没有用,也可能是().

于 2012-10-26T14:20:18.067 回答