【问题标题】:Can Scala provide type safety for array lengths?Scala 可以为数组长度提供类型安全吗?
【发布时间】:2018-11-28 22:05:56
【问题描述】:

我希望在编译时检查数组大小是否兼容。

例如这里的 zip 和 transpose 是安全的,因为 a 和 b 的长度相同:

(a: Seq[Int]) => { val b=a.map(_+1); Seq(a,b).transpose }

而这是不安全的,因为如果 a 和 b 具有不同的维度,代码将在运行时终止:

(a: Seq[Int], b: Seq[Int]) => Seq(a,b).transpose

一般来说,如果我给一些代码提供参数的维度,通常可以确定代码中每个变量的维度,最后确定代码的结果。有时这种静态分析可能会立即显示错误,有时静态分析可能会警告一些假设,例如假设两个文件具有相同的长度,可以并且应该在运行时尽快检查的假设。这将使代码更可靠,所以我喜欢这样的检查。

我在谷歌上搜索过,发现了很多讨论,但没有实际的实现。

我希望这在编译时失败:

Seq(Seq(1,2,3),Seq(1,2)).transpose

我希望它发出一个编译器警告,如果 a 不是维度 [2],这将失败:

(a: Seq[Int]) => Seq(a, Seq(1,2)).transpose

我希望这个(或类似的)不发出编译器警告:

(a: Seq[Int]) => a.length match {
case 2 => Seq(a, Seq(1,2)).transpose
case _ => throw new Exception(s"a has the wrong dimension")
}

【问题讨论】:

    标签: scala


    【解决方案1】:

    scala 标准库没有这样的东西,而且很难自己完成,但您可以使用 Shapeless,它基本上可以做到这一点(有很多警告)。

    【讨论】:

    • 一个警告是在编译时需要知道大小,看起来!这意味着它无法检测(a: Seq[Int]) => Seq(a, a++a).transpose 是否是个好主意。
    • @MaxMurphy 当然可以!如果a 的长度为n,那么a ++ a 的长度为n + n。这些不一定相等,因此您将被阻止使用transpose(尽管您必须先 write 转置,但它似乎)。事实上,您知道n 的事实阻止了transpose 的使用。如果您知道n = 0,那么您就可以使用transpose。但是,因为你不这样做,所以你不能(因为n 可能是1,编译器考虑了这种可能性)。另请注意,在编译时不需要知道大小。想想存在主义。
    猜你喜欢
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多