Array programming languages(也称为向量或多维语言)概括了对标量的操作,以便透明地应用于向量,矩阵和更高维数组。
是否有可能在Scala中实现这种代码重用?
答案 0 :(得分:5)
没有任何真正的方法来自动提升Scala操作,就像你需要支持像APL和J这样的数组编程语言。在Scala中最接近数组自动提升的是隐式转换,这不是完全正确。 Scala隐式转换采用相反的方式,转换操作的目标,而不是操作本身。即使这样,Scala隐式转换也不会链接,所以即使你可以将标量操作提升到矢量(你不能),也不会自动将其提升到2-D或更高的数组。
简而言之,在Scala中进行APL / J-ish计算将涉及很多地看到“map”和“flatMap”方法,明确调用(以及折叠,缩小,扫描和所有其他常见的嫌疑人) )。一个好处是,您可以将这些操作编码为Scala中的for-understanding,这可以为集合上的这些批处理操作提供一些令人钦佩的清晰度。
答案 1 :(得分:5)
类似于scalala您要找的东西吗?
答案 2 :(得分:5)
完全有可能(我自己这样做了)有适当的暗示,但结果并不总是像从头开始设计的那种语言完全无缝。
例如,假设您希望将整数数组视为向量,并希望能够将它们相互添加到标量中。您必须自己定义操作 - Scala无法猜测+
在数组上应该是什么意思。 (也好,因为*
通常在矩阵上没有明显的逐元素含义,而且在卷积方面它意味着另外的东西!)你可以
class ArraysAdd(a: Array[Int]) {
def +(i: Int) = a.map(_ + i)
def +(b: Array[Int]) = {
if (b.length==a.length) (a,b).zipped.map(_ + _).toArray
else throw new IllegalArgumentException
}
}
class ScalarAddsToArray(i: Int) {
def +(a: Array[Int]) = a.map(_ + i)
}
implicit def array2addable(a: Array[Int]) = new ArraysAdd(a)
implicit def scalar2arrayaddable(i: Int) = new ScalarAddsToArray(i)
然后你可以对整数数组进行数学运算:
scala> Array(1,2,3) + 5
res2: Array[Int] = Array(6, 7, 8)
scala> Array(1,7) + Array(3,2)
res3: Array[Int] = Array(4, 9)
scala> 4 + Array(-2,-3,-1)
res4: Array[Int] = Array(2, 1, 3)
如果要覆盖所有数据类型,它会变得更加棘手(至少需要使用泛型和数字 - 或者编写代码生成器来覆盖您需要的案例),为了提高效率,您可能需要创建自定义“矩阵“类而不是坚持使用额外功能包装的原始数组。
这包括基本操作。对于math.sqrt
等数学函数,如果您不介意键入a map sqrt
而不是sqrt(a)
,则无需执行任何操作。否则,你可以自己超载;乏味,但它可以让你透明地使用它们。
或者您可以使用已经为您完成了大部分工作的库。 (斯卡拉拉是我所知道的最好的矩阵候选者。)