我想与Netwire一起使用线性代数库。由于Netwire的类型是Applicative
的实例,因此它为自动化liftA2
的类型提供了Num
和Fractional
实例。这很好,因为您可以做一些乘坐时变值之类的事情,而无需任何额外的努力。
我一直在使用线性,但是它的功能被定义为非*
类型的多态性,即矩阵产品:
(!*!) :: (Functor m, Foldable t, Additive t, Additive n, Num a)
=> m (t a) -> t (n a) -> m (n a)
这意味着,如果我没有误解的话,我无法为Additive
和Company定义实例,因为没有理智的形式可以采用。虽然我可以写
instance Num b => Num (Wire s e m a b) where ...
没有办法写
instance Additive n => Additive (Wire s e m a (n x)) where ...
因为(Wire s e m a (n x))
的种类错误(*
与* -> *
相反)。我见过的其他库根本不是多态。
我想知道的是,哪些线性代数库是多态性的*
?
我看过VEC,看起来更好。它的矩阵倍数具有类型
(Map v v' m1 m3, Map v a b v', Transpose m2 b, Fold v a, Num v, Num a)
=> m1 -> m2 -> m3
这就是我想要的。还有其他库吗?
有矢量空间,在许多方面,这实际上比在其标量上参数的库更优雅(VectorSpace
代替该字段是相关的类型同义词)。
我喜欢的一部分是,它完全不是基于 free 向量空间,这意味着基于Foldables
的签名首先没有任何意义。(的确,它根本不谈论矩阵,只谈论线性映射,而线性映射仅仅是向量空间类别的形态)
instance (AdditiveGroup a) => AdditiveGroup (Wire a) where
...
instance (VectorSpace v) => VectorSpace (Wire v) where
type Scalar (Wire v) = Scalar v -- Or perhaps `Wire (Scalar v)`
...
我对其他一些库进行了调查,这是我发现的:
- hmatrix-积极维护;类型
* -> *
,GPL许可 - vect -opengl bindings;不积极维护;使用硬线标量类型,因此无法提起
dot
之类的东西 - vec-积极维护;未正确载体(请参见下文);有用的辅助功能;没有opengl绑定
- 线性 - 积极维护;由谷氨酸和乙烯基GL支持;
* -> *
类 - 矢量空间 - 积极维护;正确负载;OpenGL绑定,但仅适用于向量;一个小时后,我仍然不知道如何使用它,尤其是线性映射
- 张量 - 内置在OpenGL中;没有数学功能
- 床和早餐 - 积极维护;使用未包装的数组;在价值类型上使用类型的家庭,因此可能会超载,但看起来很奇怪(即
Matrix (Wire s e m a Double)
是载有矩阵的电线);没有OpenGL接口
这消除了除vec,矢量空间和床和休息时间之外的所有内容。怪异的类型消除了床和休息时间(不幸的是,因为否则它很好)。最终,VEC最终仅赢得了矢量空间的胜利,因为它似乎是为图形而不是抽象代数研究而设计的。而且因为我似乎无法弄清楚如何使用线性地图进行视角转换。
我必须编写一个OpenGL接口(因为它已经是Storable
,这还不错)。唯一的缺点是,我想不到辅助函数的维度依赖性参数/结果的明智类型(即rotationX :: Floating a => a -> Mat44 a
)。这是我用vec丢失的向量空间的优势之一。
更新:VEC将行不通。这些类不仅用于结果类型,还包括将其放入向量的类型。例如,Fold
类。
最终更新:我最终放弃了这个想法,并为Wire
s。