绑定类型参数 [英] Bind type parameter
问题描述
我目前正在使用相当漂亮的 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:我很清楚特征矩阵有一个索引函数,但是
- 我希望它与其他数据类型共同使用
编辑:添加了提到的软件包的参考链接。
解决方案你快到了。一个缺失的部分是必须使用
类型
同义词饱和 - 也就是说,您必须提供所有参数。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
- I want it to be a common one with other data types
- 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, onlyMatX a
. The reason for this is thattype
synonyms are just synonyms - they're expanded at compile time, which means that the compiler needs to know all of thetype
synonym's arguments in order to get a valid type after expansion.The fix is to change your
type
synonym to anewtype
.newtype MatX a = MatX { getMatX :: Matrix a (CType a) }
newtype
s can be partially applied, becauseMatX a
is now a different type toMatrix a (CType a)
.type instance Key MatX = (Int, Int)
这篇关于绑定类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!