haskell - Haskell 类型同义词可以用作类型构造函数吗?
问题描述
我正在编写一个基准来比较多个 Haskell 集合的性能,包括STArray
在给定任务上的性能。为了消除重复,我尝试编写一组函数,为这些集合提供统一接口,以便我可以将任务实现为多态高阶函数。更具体地说,该任务是根据多态 monad 来实现的,它ST s
用于STArray
和Identity
类似的集合HashMap
,通常不需要在 monad 中进行操作。
由于统一性要求,我不能直接使用Identity
andHashMap
类型,因为我需要它们的种类来匹配ST
and的种类STArray
。我认为实现这一点的最简单方法是使用幻像参数定义类型同义词:
type Identity' s a = Identity a
type HashMap' s i e = HashMap i e
-- etc.
不幸的是,这不起作用,因为当我尝试在我使用的地方ST
和类型构造函数中使用这些同义词作为类型构造函数时STArray
,GHC 会给出如下错误:
The type synonym ‘Identity'’ should have 2 arguments, but has been given none
我遇到了-XLiberalTypeSynonyms
GHC 扩展,并认为它可以让我这样做,如文档所述:
您可以将类型同义词应用于部分应用的类型同义词
并给出了这样做的例子:
type Generic i o = forall x. i x -> o x
type Id x = x
foo :: Generic Id []
该示例适用于 GHC 8.0.2(使用-XExistentialQuantification
and -XRank2Types
)。但是根据我的用例的需要,Generic
用newtype
ordata
声明替换是行不通的。即以下代码导致我上面报告的相同类型的错误:
newtype Generic i o = Generic (forall x. i x -> o x)
type Id x = x
foo :: Generic Id []
foo = Generic (\x -> [x])
问题
是否需要启用其他一些扩展才能使其正常工作?如果没有,是否有充分的理由说明这不起作用,还是只是疏忽?
解决方法
我知道我可以通过将Identity'
等定义为成熟的类型来解决这个问题,例如:
newtype Identity' s a = Identity' a
newtype Collection collection s i e = Collection (collection i e)
-- etc.
但这并不理想,因为这意味着我必须重新实现Identity
's和'sFunctor
的实例,这意味着我必须为集合编写额外的包装和展开代码。Applicative
Monad
Identity'
解决方案
推荐阅读
- reporting-services - SSRS 在不应该添加新页面时添加
- cpu - 流水线处理器中时钟寄存器的目的是什么
- babeljs - 自 7 升级以来的 Babel 文档非常混乱
- c# - 使用 HTMLAgilityPack 在特定位置注入 HTML
- lazarus - 编译后执行一些脚本
- android - 尝试使用复选框发送意图时,应用程序在启动时崩溃
- php - Laravel 5.7 - 为什么以编程方式列出控制台命令返回 0?
- html - 将图像的上半部分推到卡片外面
- python - sqlite3.OperationalError:靠近“........”:语法错误
- python - 无法使用 Subprocess 模块成功解析和运行长命令