首页 > 解决方案 > Haskell 类型同义词可以用作类型构造函数吗?

问题描述

我正在编写一个基准来比较多个 Haskell 集合的性能,包括STArray在给定任务上的性能。为了消除重复,我尝试编写一组函数,为这些集合提供统一接口,以便我可以将任务实现为多态高阶函数。更具体地说,该任务是根据多态 monad 来实现的,它ST s用于STArrayIdentity类似的集合HashMap,通常不需要在 monad 中进行操作。

由于统一性要求,我不能直接使用IdentityandHashMap类型,因为我需要它们的种类来匹配STand的种类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

我遇到了-XLiberalTypeSynonymsGHC 扩展,并认为它可以让我这样做,如文档所述:

您可以将类型同义词应用于部分应用的类型同义词

并给出了这样做的例子:

type Generic i o = forall x. i x -> o x
type Id x = x

foo :: Generic Id []

该示例适用于 GHC 8.0.2(使用-XExistentialQuantificationand -XRank2Types)。但是根据我的用例的需要,Genericnewtypeordata声明替换是行不通的。即以下代码导致我上面报告的相同类型的错误:

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的实例,这意味着我必须为集合编写额外的包装和展开代码。ApplicativeMonadIdentity'

标签: haskellghctype-constructortype-synonyms

解决方案


推荐阅读