Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 存在类型。为异构映射编写类实例_Haskell_Existential Type - Fatal编程技术网

Haskell 存在类型。为异构映射编写类实例

Haskell 存在类型。为异构映射编写类实例,haskell,existential-type,Haskell,Existential Type,使用以下类型和类定义,我不理解为什么在创建下面的实例时会出现错误 我需要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 d

使用以下类型和类定义,我不理解为什么在创建下面的
实例时会出现错误

我需要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
{-#语言存在量化}
模块Scratch.SO_ExtistentialTypes,其中
导入数据。映射
键入MyMap a=映射字符串a
我的c班在哪里
getMyMap::对于所有a。c->MyMap a
数据MyData=对于所有a。我的数据{
myMap::myMap a
}
实例MyClass MyData,其中

getMyMap=myMap--首先,这里的
For all
是多余的:

class MyClass c where 
    getMyMap :: forall a. c -> MyMap a
没有显式绑定的类型变量通常在最外层进行量化,因此这与just
c->MyMap a
完全相同

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

不可能让未包装的存在类型自行浮动(这需要一个与所有
对应的
exists
量词),因此无法重写
getMyMap
的类型,从而使
myMap
是一个有效的实现

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


在您的例子中,
Map
的值具有存在类型,没有其他结构或约束,因此它们几乎没有任何用处,也可能是
()

首先,这里的
对于所有
都是多余的:

class MyClass c where 
    getMyMap :: forall a. c -> MyMap a
没有显式绑定的类型变量通常在最外层进行量化,因此这与just
c->MyMap a
完全相同

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

不可能让未包装的存在类型自行浮动(这需要一个与所有
对应的
exists
量词),因此无法重写
getMyMap
的类型,从而使
myMap
是一个有效的实现

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


在您的例子中,
Map
的值具有存在类型,没有其他结构或约束,因此它们几乎毫无用处,也可能是
()

,您在这里试图实现什么?因为我非常怀疑这是一个好的方法。@C.a.McCann
类型和
类是定义“API”的模块的一部分。
数据
类型
是(简化的)暂定实现。@C.A.McCann另一种说法是:如何创建一个可以成为MyClass实例的数据类型(MyData),
getMyMap
唯一合理的定义是忽略其输入并每次返回一个空的
Map
。我假设这不是您想要的,因此您可能需要重新思考
MyClass
的用途。在类型化设置中,有一个更严格的异构映射概念是有意义的,其中值的类型取决于键的索引。您可能有
数据映射(k::*->*)=…
,然后您会有一个类似
查找::ord1k=>映射k->ka->a的函数。现在,如果将参数实例化为
Map
到一个细化其索引的GADT,则可以将不同的键映射到不同的值类型。我不久前写了一本,但现在找不到。也许这会帮你弄清楚你想要什么。你想在这里实现什么?因为我非常怀疑这是一个好的方法。@C.a.McCann
类型和
类是定义“API”的模块的一部分。
数据
类型
是(简化的)暂定实现。@C.A.McCann另一种说法是:如何创建一个可以成为MyClass实例的数据类型(MyData),
getMyMap
唯一合理的定义是忽略其输入并每次返回一个空的
Map
。我假设这不是您想要的,因此您可能需要重新思考
MyClass
的用途。在类型化设置中,有一个更严格的异构映射概念是有意义的,其中值的类型取决于键的索引。您可能有
数据映射(k::*->*)=…
,然后您会有一个类似
查找::ord1k=>映射k->ka->a的函数。现在,如果将参数实例化为
Map
到一个GADT,该GADT细化了它的索引,那么可以使用不同的