【发布时间】:2017-02-02 10:21:55
【问题描述】:
我目前正在使用相当不错的haskell-eigen 库,偶然发现了一个基本但可能是基本的问题(我对实际的haskell 开发很陌生)。
我使用他们的基本矩阵类型
data Matrix a b :: * -> * -> *
其中a 表示haskell,b 表示内部C 类型。这是通过限制实现的
Elem a b
与
Elem Double CDouble
Elem Float CFloat
-- more for complex types...
虽然不是我想在这里问的问题,但我有点不明白为什么要这样做。由于它显然是一种函数映射,我已经不明白为什么将其表述为等价关系,但无论如何......
我现在想从keys 包中定义(作为一个简单的例子——我有几个)Key 的一个实例。它定义了给定容器的索引键,例如
type instance [] = Int
所以 Key 的实例是在 * -> * 类型上定义的。
但是由于该要求,这将不起作用:
type instance Key Matrix = (Int, Int)
我必须以某种方式使 Matrix 变得亲切 * -> *。所以(来自 c++,我会使用特征类来做到这一点),我尝试了这个:
type family CType a where
CType Double = CDouble
CType Float = CFloat
type MatX a = Matrix a (CType a)
换句话说,我尝试使用类型同义词作为实现上述功能类型映射的一种手段。
现在我尝试了以下方法:
type instance Key MatX = (Int, Int)
这给了我“类型同义词‘MatX’应该有 1 个参数,但没有给出任何参数”,我什至尝试了明显错误的方法
type instance Key (MatX a) = (Int, Int)
这给了我“预期的种类 * -> *,但 MatX a 有种类 *”。这对我来说听起来像是“我的编译器期望一个类型超过 0 但 - 作为类型同义词 - 少于 1 个参数”。
所以我的问题是:通常如何在 haskell 中映射类型以解决这种不匹配或以另一种方式摆脱它。
P.S.:我很清楚本征矩阵有索引功能,但是
- 我希望它与其他数据类型通用
- 我在其他类型实例的其他变体中遇到了这个问题。
编辑:添加了提到的包的参考链接。
【问题讨论】:
-
老实说,我会摆脱问题的前半部分。您可以使用
data Two a b = T完全重现该行为。另外,请确保包含指向软件包的链接。顺便说一句,stackoverflow.com/questions/2335967/… 与您要查找的内容很接近。 -
Elem类具有函数依赖关系,因此它表达了函数关系。函数依赖的存在时间比类型族长得多,并且在某些情况下还提供更好的 API(尽管我认为在这种情况下可能不是)。 -
@dfeuer:这很有趣。我有点假设类型上的功能映射太基础了,根本不存在;)。还要注意,在这些情况下,等价关系是完全错误的。没有什么能阻止我拥有多个 (Elem Float Anything) 实例。当然,编译器不会允许歧义,但对我来说,将函数依赖限制为实际函数(在数学意义上)似乎更合理。不会想到在类型级别上,早期的 haskell 更像是 Prolog 而不是 Haskell...
-
谁说过等价关系?函数依赖意味着你不能拥有多个
Elem Float实例。第二个参数由第一个参数决定。今天,这仅用于类型检查,但我希望函数依赖最终会像类型族一样实现,以便提供适当的证据。
标签: haskell