绑定类型参数 [英] Bind type parameter

查看:133
本文介绍了绑定类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用相当漂亮的 haskell-eigen 图书馆,并偶然发现了一个根本性的可能的基本问题(我对于实际的haskell开发很陌生)。

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

 数据Matrix ab :: *  - > *  - > * 

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

  Elem ab 



  Elem Double CDouble 
Elem Float CFloat
- 更复杂的类型...

尽管我不想问这里的问题,不明白为什么这样做是这样做的。由于它显然是一种功能映射,我已经不明白为什么这是作为一个等价关系公式化的,但无论如何...

现在我想定义(作为一个简单的例子 - 我有几个),其中包含。它定义给定容器的索引键,例如

  type instance [] = Int 


$ b

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



然而,由于这个要求,这是行不通的:

 类型实例键矩阵=(Int,Int)

我必须以某种方式使Matrix成为* - > *。因此(来自c ++,我会用traits类来做这件事),我试过这个:

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

类型MatX a =矩阵a(CType a)

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



现在我尝试了如下:

  type实例键MatX =(Int,Int)

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


$ b $

 类型实例键(MatX a)=(Int,Int)

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

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



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


  1. 我希望它与其他数据类型共同使用

编辑:添加了提到的软件包的参考链接。

解决方案

你快到了。一个缺失的部分是必须使用类型同义词饱和 - 也就是说,您必须提供所有参数。 MatX 本身不是有效的类型,只有 MatX a 。原因是类型同义词只是同义词 - 它们在编译时展开,这意味着编译器需要知道所有的键入同义词的参数,以便在扩展后得到一个有效的类型。



解决方法是更改​​您的 code>同义词a newtype

  newtype MatX a = MatX {getMatX :: Matrix a(CType a)} 

newtype s can 可以部分应用,因为 MatX a 现在是与不同的类型Matrix a CType a)

 类型实例键MatX =(Int,Int)


I am currently working with the quite nice haskell-eigen library and stumbled upon a fundamental yet probably basic problem (I am quite new to practical haskell development).

I use their basic matrix type

data Matrix a b :: * -> * -> *

where a denotes the haskell and b the internal C type. This is realized via the restriction

Elem a b

with

Elem Double CDouble
Elem Float CFloat
-- more for complex types...

Although not really the question I want to ask here I kind of don't understand why this is done this way. Since it is obviously a kind of functional mapping I already don't understand why this is formulated as an equivalency relation, but anyway...

I now want to define (as a simple example - I got several) an instance of Key from the keys package. It defines the index key for a given container, for example

type instance [] = Int

So instances of Key are defined over types of kind * -> *.

However due to that requirement, this won't work:

type instance Key Matrix = (Int, Int)

I have to in some way make Matrix be of kind * -> *. So (coming from c++ where I would do this using traits classes), I tried this:

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

type MatX a = Matrix a (CType a)

In other words I tried to use type synonyms as a means of realizing that above mentioned functional type map.

Now I tried the following:

type instance Key MatX = (Int, Int)

which gives me "The type synonym ‘MatX’ should have 1 argument, but has been given none" and I even tried the obviously wrong

type instance Key (MatX a) = (Int, Int)

which gives me "Expected kind * -> *, but MatX a has kind *". This sounds to me like "I the compiler expect a type with more than 0 but - being a type synonym - less than 1 argument".

So my question is: How does one commonly map types in haskell in order to solve such a kind mismatch or get rid of it in another way.

P.S.: I am well aware that the eigen matrix has an indexing function, but

  1. I want it to be a common one with other data types
  2. I have this problem in other variants for other type instances.

Edit: Added reference links to mentioned packages.

解决方案

You're nearly there. The one missing piece is that type synonyms must be used saturated - that is, you have to supply all of its arguments. MatX on its own is not a valid type, only MatX a. The reason for this is that type synonyms are just synonyms - they're expanded at compile time, which means that the compiler needs to know all of the type synonym's arguments in order to get a valid type after expansion.

The fix is to change your type synonym to a newtype.

newtype MatX a = MatX { getMatX :: Matrix a (CType a) }

newtypes can be partially applied, because MatX a is now a different type to Matrix a (CType a).

type instance Key MatX = (Int, Int)

这篇关于绑定类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆