12

次の壊れた関数を考えてみましょう。

def sum (list : Seq[Int]) : Int = list match {
  case Nil => 0
  case head :: tail => head + sum(tail)
}

ここで、関数は で動作するはずでしたList[Int]が、代わりに受け入れるようにリファクタリングされたためSeq[Int]、コンパイラが気付かないうちに壊れてしまいました。

Scala の不完全なパターン一致検出のこの大きな穴により、ほとんど役に立たなくなります。

このような問題を体系的に検出する方法が必要です。具体的には、すべてのガイド付きパターン マッチでコンパイラにエラー/警告をinstanceof発行させたいと考えています。つまり、シールされた階層とカスタム マッチャーでのみパターン マッチを許可したいと考えています。

パターン マッチングの安全性の保守的な (恣意的ではなく) チェックを行う既存のコンパイラ オプション/プラグインはありますか?

4

2 に答える 2

3

Nil::は明らかに a を構築する方法ですが、たまたまListすべての uence が であるわけではないため、Scala 型チェッカーはこのプログラムを型が正しくないとして拒否すると予想されます。右?SeqLists

違う。これを試してみると、私が何を意味するかがわかります。

def sum (list : Seq[Int]) : Int = list match {
  case Nil => 0
  case head :: tail => head + sum(tail)
  case _ => -1
}

> sum(Array(1,2,3).toSeq)
res1: Int = -1
> sum(List(1,2,3))
res2: Int = 6

ご覧のとおり、一部の Sequencesはandで分解できる可能性があります。できないものは、パターン マッチに失敗して先に進み、次のマッチを試みます。とは、 のすべての可能性をカバーするのに十分ですが、 の場合はそうではありません。ここでは、サブタイピング、利便性、および型の安全性の間にトレードオフがあります。現時点での解決策は次のとおりです。リファクタリングするときはもっと注意してください。Nil::Nil::ListSeq

于 2012-01-18T17:28:24.473 に答える
3

M. Oderskyによるこの回答をご覧ください。

概要

封印されていない階層の一致のチェックは実行可能ですが、簡単ではなく、(まだ) 実装されていません。

于 2012-01-18T14:52:36.063 に答える