类型安全的矩形多维数组类型

2024-01-30

你如何代表一个矩形的Scala 中的二维(或多维)数组数据结构?

也就是说,每行的长度相同,编译时验证,但是尺寸是在运行时确定的?

Seq[Seq[A]]具有所需的接口,但它允许用户提供“参差不齐”的数组,这可能导致运行时失败。

Seq[(A, A, A, A, A, A)](和类似的)确实验证长度是否相同,但它也强制在编译时指定该长度。

界面示例

这是我的意思的示例接口(当然,内部维度不必是元组;它可以指定为列表或其他类型):

// Function that takes a rectangular array
def processArray(arr : RectArray2D[Int]) = {
    // do something that assumes all rows of RectArray are the same length
}

// Calling the function (OK)
println(processArray(RectArray2D(
    ( 0,  1,  2,  3),
    (10, 11, 12, 13),
    (20, 21, 22, 23)
)))
// Compile-time error
println(processArray(RectArray2D(
    ( 0,  1,  2,  3),
    (10, 11, 12),
    (20, 21, 22, 23, 24)
)))

这可以使用无形的 https://github.com/milessabin/shapeless图书馆的规模类型:

import shapeless._

def foo[A, N <: Nat](rect: Seq[Sized[Seq[A], N]]) = rect

val a = Seq(Sized(1, 2, 3), Sized(4, 5, 6))
val b = Seq(Sized(1, 2, 3), Sized(4, 5))

Now foo(a)编译,但是foo(b)没有。

这使我们能够编写非常接近您想要的界面的东西:

case class RectArray2D[A, N <: Nat](rows: Sized[Seq[A], N]*)

def processArray(arr: RectArray2D[Int, _]) = {
  // Run-time confirmation of what we've verified at compile-time.
  require(arr.rows.map(_.size).distinct.size == 1)
  // Do something.
}

// Compiles and runs.
processArray(RectArray2D(
  Sized( 0,  1,  2,  3),
  Sized(10, 11, 12, 13),
  Sized(20, 21, 22, 23)
))

// Doesn't compile.
processArray(RectArray2D(
  Sized( 0,  1,  2,  3),
  Sized(10, 11, 12),
  Sized(20, 21, 22, 23)
))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

类型安全的矩形多维数组类型 的相关文章

随机推荐