声明用于N个N个元素矩阵与N个元素列向量相乘的类型类 [英] Declaring a type class for multiplication of an N-by-N-element matrix and an N-element column vector

查看:97
本文介绍了声明用于N个N个元素矩阵与N个元素列向量相乘的类型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Haskell中,如果您具有类型的族"(例如,对于N的某些值,则为N个元素的矩阵)和相关"类型的并行族(例如,N个元素的向量) ,对于相同的N值),以及需要每个族中一种特定类型的操作(例如,将N×N元素矩阵与N元素列向量相乘),则可以声明类型该操作的课程?

In Haskell, if you have a "family" of types (say, N-by-N-element matrices, for some values of N), and a parallel family of "related" types (say, N-element vectors, for the same values of N), and an operation that requires one specific type from each family (say, multiplying an N-by-N-element matrix and an N-element column vector), is it then possible to declare a type class for that operation?

对于这个特定的示例,我想它看起来像这样:

For this specific example, I imagine it would look something like this:

class MatrixNxN m where

  --| Multiplication of two N-by-N-element matrices
  mmul :: Num a => m a -> m a -> m a

  --| Multiplication of an N-by-N-element matrix and an N-element column vector
  vmul :: Num a => m a -> v a -> v a

但是,我不知道如何限制类型v.可以做这样的事情吗?

I don't know how to constrain the type v, however. Is it possible to do something like this?

请注意,我既欢迎对声明多个相关类型的类型类的一般问题的解答,也对为矩阵向量乘法声明类型类的特定问题的解答表示欢迎.在我的特定情况下,只有一小部分已知的N值(2、3和4),但是我通常对理解Haskell的类型系统中可能进行编码的内容感兴趣.

Please note that I welcome both answers to the general question of declaring a type class of multiple, related types, as well as answers to the specific question of declaring a type class for matrix-vector multiplication. In my specific case, there is only a small, known set of values of N (2, 3, and 4), but I'm generally interested in understanding what is possible to encode in Haskell's type system.

编辑:我使用 MultiParamTypeClasses 实施了此操作和 FunctionalDependencies ,如下面的加布里埃尔·冈萨雷斯(Gabriel Gonzalez)和MFlamer所建议.这就是我实现的相关部分最终看起来像什么:

I implemented this using MultiParamTypeClasses and FunctionalDependencies as suggested by Gabriel Gonzalez and MFlamer below. This is what the relevant bits of my implementation ended up looking like:

class MatrixVectorMultiplication m v | m -> v, v -> m where
  vmul :: Num a => m a -> v a -> v a

data Matrix3x3 a = ...
data Vector3 a = ...

instance MatrixVectorMultiplication Matrix3x3 Vector3 where
  vmul = ...

这是vmul的类型签名,它本身并已部分应用:

This is the type signature of vmul, on its own and partially applied:

vmul :: (Num a, MatrixVectorMultiplication m v) => m a -> v a -> v a
(`vmul` v) :: Matrix3x3 Integer -> Vector3 Integer
(m `vmul`) :: Vector3 Integer -> Vector3 Integer

我觉得这一切都很优雅.感谢您的回答! :)

I find this all very elegant. Thanks for the answers! :)

推荐答案

这是对MFlamer答案的很小的改动,这也使得m依赖于v:

This is a very tiny variation on MFlamer's answer, which also makes m dependent on v:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

class MatrixNxN m v | m -> v, v -> m where
    mmul :: Num a => m a -> m a -> m a
    vmul :: Num a => m a -> v a -> v a

那样,如果您这样做:

(`vmul` someVector)

...,则编译器可以仅根据someVector的类型选择正确的实例.

... then the compiler can select the correct instance on the basis of someVector's type alone.

类型族解决方案由于相同的原因而无法工作,主要是因为如果您声明v类型构造函数为m类型构造函数的类型函数,则该类型函数不一定是1-to- 1,因此编译器将无法从v推断m.这就是为什么人们说功能依赖比类型族更强大的原因.

The type family solution won't work for the same reason, mainly because if you declare the v type constructor to be a type function of the m type constructor, that type function is not necessarily 1-to-1, so the compiler wouldn't be able to infer m from v. This is why people say that functional dependencies are more powerful than type families.

这篇关于声明用于N个N个元素矩阵与N个元素列向量相乘的类型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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