类型安全的矩形多维数组类型 [英] Type-safe rectangular multidimensional array type

查看:103
本文介绍了类型安全的矩形多维数组类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你如何重新present一个长方形 2维的斯卡拉(或多维)数组?

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

序列[SEQ [A] 具有所需的接口,但它允许用户提供衣衫褴褛数组,这可能会导致在运行时出现故障

序列[(A,A,A,A,A,A)] (或类似),并确认长度是相同的,但它也迫使这在编译时指定的长度。

示例接口

下面是说明我的意思的示例界面(当然,内部尺寸不必是元组;它可被指定为列表或一些其它类型的):

  //功能,需要一个矩形阵列
高清processArray(ARR:RectArray2D [INT])= {
    //做一些假设RectArray的所有行具有相同的长度
}//调用函数(OK)
的println(processArray(RectArray2D(
    (0,1,2,3),
    (10,11,12,13),
    (20,21,22,23)
)))
//编译时错误
的println(processArray(RectArray2D(
    (0,1,2,3),
    (10,11,12),
    (20,21,22,23,24)
)))


解决方案

这是可以使用无形库的大小类型:

 进口shapeless._DEF为foo [A,N&LT ;:纳特(RECT:序号[大中[SEQ [A],N])= RECTVAL一个= SEQ(大小(1,2,3),大中(4,5,6))
VAL B = SEQ(大小(1,2,3),大小(4,5))

现在美孚(一)编译,但富(二)没有。​​

这让我们写的东西非常接近你想要的接口:

 案例类RectArray2D [A,N&LT ;:纳特(行:大中[SEQ [A],N] *)高清processArray(ARR:RectArray2D [诠释,_])= {
  //什么,我们已经在编译时验证运行时间确认。
  需要(arr.rows.map(_。大小).distinct.size == 1)
  // 做一点事。
}//编译和运行。
processArray(RectArray2D(
  尺寸(0,1,2,3),
  尺寸(10,11,12,13),
  尺寸(20,21,22,23)
))//不能编译。
processArray(RectArray2D(
  尺寸(0,1,2,3),
  尺寸(10,11,12),
  尺寸(20,21,22,23)
))

How do you represent a rectangular 2-dimensional (or multidimensional) array data structure in Scala?

That is, each row has the same length, verified at compile time, but the dimensions are determined at runtime?

Seq[Seq[A]] has the desired interface, but it permits the user to provide a "ragged" array, which can result in a run-time failure.

Seq[(A, A, A, A, A, A)] (and similar) does verify that the lengths are the same, but it also forces this length to be specified at compile time.

Example interface

Here's an example interface of what I mean (of course, the inner dimension doesn't have to be tuples; it could be specified as lists or some other type):

// 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)
)))

解决方案

This is possible using the Shapeless library's sized types:

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) compiles, but foo(b) doesn't.

This allows us to write something very close to your desired interface:

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)
))

这篇关于类型安全的矩形多维数组类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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