绑定类型参数

Ric*_*ock 1 haskell

我目前正在使用相当不错的haskell-eigen库,偶然发现了一个基本但可能是基本的问题(我对实用的haskell开发很新).

我使用他们的基本矩阵类型

data Matrix a b :: * -> * -> *
Run Code Online (Sandbox Code Playgroud)

其中a表示haskell,b表示内部C类型.这是通过限制实现的

Elem a b
Run Code Online (Sandbox Code Playgroud)

Elem Double CDouble
Elem Float CFloat
-- more for complex types...
Run Code Online (Sandbox Code Playgroud)

虽然这不是我想问的问题,但我有点不明白为什么这样做.由于它显然是一种功能映射,我已经不明白为什么这被制定为等效关系,但无论如何......

我现在想要定义(作为一个简单的例子 - 我有几个)来自keys包的Key实例.例如,它定义了给定容器的索引键

type instance [] = Int
Run Code Online (Sandbox Code Playgroud)

所以Key的实例是在类型* - >*上定义的.

但是由于这个要求,这不起作用:

type instance Key Matrix = (Int, Int)
Run Code Online (Sandbox Code Playgroud)

我必须以某种方式使Matrix变得善良* - >*.所以(来自c ++,我会用traits类来做),我试过这个:

type family CType a where
    CType Double = CDouble
    CType Float = CFloat

type MatX a = Matrix a (CType a)
Run Code Online (Sandbox Code Playgroud)

换句话说,我试图使用类型同义词作为实现上述功能类型映射的手段.

现在我尝试了以下内容:

type instance Key MatX = (Int, Int)
Run Code Online (Sandbox Code Playgroud)

这给了我"类型同义词'MatX'应该有1个参数,但没有给出"我甚至尝试了明显错误

type instance Key (MatX a) = (Int, Int)
Run Code Online (Sandbox Code Playgroud)

这给了我"预期的种类* - >*,但是MatX a有种类*".这听起来像"我编译器期望一个类型超过0但是 - 是一个类型的同义词 - 少于1个参数".

所以我的问题是:如何通常在haskell中映射类型以解决这种类型的不匹配或以另一种方式摆脱它.

PS:我很清楚特征矩阵具有索引函数,但是

  1. 我希望它是与其他数据类型共同的
  2. 我在其他类型实例的其他变体中遇到此问题.

编辑:添加了提到的包的参考链接.

Ben*_*son 5

你快到了.缺少的一个是type必须使用饱和的同义词- 也就是说,你必须提供它的所有参数.MatX仅靠它本身不是有效类型MatX a.这样做的原因是type同义词只是同义词 - 它们在编译时被扩展,这意味着编译器需要知道所有type同义词的参数,以便在扩展后获得有效类型.

修复方法是将您的type同义词更改为newtype.

newtype MatX a = MatX { getMatX :: Matrix a (CType a) }
Run Code Online (Sandbox Code Playgroud)

newtypes 可以部分应用,因为MatX a现在是不同的类型Matrix a (CType a).

type instance Key MatX = (Int, Int)
Run Code Online (Sandbox Code Playgroud)