samthebestの答えはおそらく本当の理由(私は知らない、それは私が精通してるものではないのです)で、より一般的に関数型プログラミングに関連する別の方法があります。
よくあなたが
sealed trait List[+T]
case object Nil extends List[Nothing]
case class Cons[+T](head: T, tail: List[T]) extends List[T]
を書くとき単語sealed
は、関数型プログラミングでの試合は、この解釈で
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))
(Church Encoding)特別な言語の機能を使用せずに行うことができることが知られています値/用語はmatch
機能を提供します。
あなたの質問を読む1つの方法は、そうするのではなく、なぜですか?統語的なマッチを提供するのではなく、他の基本的な言語機能からマッチを構築してみませんか?
重複マッチ機能:
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 => ???
}
これは
理由は、構文match
は人のように、いくつかの構文糖を提供することです構文的な砂糖なしで書くのは非常に厄介です。あなたはそれを行うことができます。私は可能性を探ってみた。trying to implement monadic extractors;確かにあまりにもかわいいです。
オープンとクローズドマッチ機能の自動選択。
つまり、Scalaのエクストラクタはオープンマッチ関数のようになります。これは、いずれも失敗する可能性があるため、None
を返します。コンパイラは完全なmatch
をチェックしませんが、好きなだけ連鎖させることができ、Scalaは最初のものを選択します。一方、sealed
形質は完全一致チェックの恩恵を受けるクローズドマッチ機能を提供する。これらは別々の関数で提供する必要がありますが、Scalaでは両方に対して同じmatch
構文を使用できます。
個人的に私は、上記の要件で最終的にマッチのための特別な構文サポートが必要ではないという疑いがあります。私は他のより一般的な言語機能が、特にネストされたマッチの領域で同じ利点をもたらすことになると考えています。しかし当面は、特別なmatch
構文を使用して直接問題を突き止めるのが理にかなっています。
マクロを使ってマッチを実装するメリットはありますか?特に*に一致する*仮想化パターンがあるとします。 –
@ om-nom-nom:わかりません - 私は学習/理解のために質問しました。しかし、特別なケースを削除することは、当初は明らかではないメリットがあることを知っています。また、私は*仮想化されたパターンマッチング*についてこれまで知りませんでしたが、今のところそれをチェックしています。 –
@ om-nom-nom:私がhttp://stackoverflow.com/questions/8533826/what-is-scalas-experimental-virtual-pattern-matcherから学んだことに基づいて、私は「はい」と答えるでしょうあなたの質問の第二の部分。 –