samthebest の答えはおそらく本当の理由です (私にはわかりませんが、それは私がよく知っているものではありません) が、より一般的に関数型プログラミングに関連する別の見方があります。
関数型プログラミングでの照合は、特別な言語機能 ( Church Encoding )なしで実行できることはよく知られています。
trait List[+T] {
def mmatch[R](nil: => R, cons: (T, List[T]) => R): R
}
object Nil extends List[Nothing] {
def mmatch[R](nil: => R, cons: (Nothing, List[Nothing]) => R) = nil
}
class Cons[+T](head: T, tail: List[T]) extends List[T] {
def mmatch[R](nil: => R, cons: (T, List[T]) => R) = cons(head, tail)
}
def sum(l: List[Int]): Int = l mmatch (
nil = 0,
cons = (x, xs) => x + sum(xs)
)
val list = new Cons(1, new Cons(2, Nil))
println(sum(list))
この解釈では、あなたが書くとき
sealed trait List[+T]
case object Nil extends List[Nothing]
case class Cons[+T](head: T, tail: List[T]) extends List[T]
単語sealed
は、機能を提供する値/用語ですmatch
。
あなたの質問を読む一つの方法は、なぜそれをしないのですか? 構文の一致を提供するのではなく、他の基本的な言語機能から一致を作成してみませんか?
その理由は、構文match
が人々が好むいくつかの構文糖衣を提供するためです。
一致関数の重複:
sealed trait A
sealed trait B
case object X extends A
case object Y extends A with B
case object Z extends B
ネストされた一致関数:
(1 :: 2 :: Nil) match {
case x :: y :: Nil => ???
}
これは、構文糖衣なしで書くのは非常に厄介です。あなたならできます。モナド抽出器を実装しようとするとき、可能性を探ってみました。しかし、それは確かにあまりきれいではありません。
オープン vs クローズマッチ関数の自動選択。
つまり、Scala のエクストラクターはオープン マッチ関数のようなものNone
です。コンパイラは完全なものをチェックしませんmatch
が、好きなだけ連鎖させることができ、Scala は最初のものを選択します。一方、sealed
トレイトは、完全性チェックの利点を備えたクローズド マッチ関数を提供します。これらは別々の関数で提供する必要がありますが、Scala ではmatch
両方に同じ構文を使用できます。
個人的には、上記の要件は、最終的に、一致のための特別な構文サポートを必要としないのではないかと疑っています。私は、他のより一般的な言語機能が、特にネストされた一致の領域で、同じ利点をもたらす可能性があると考えています。ただし、当面は、特別なmatch
構文を使用して問題を直接解決する方が理にかなっています。