1

n+k パターンを unapply 経由で scala のアクティブ パターンとして実装できると思ったのですが、失敗するようですunspecified value parameter: k

object NPlusK {
    def apply(n : Int, k : Int) = {
        n + k
    }    

    def unapply(n : Int, k : Int) = {
        if (n > 0 && n > k) Some(n - k) else None
    }
}

object Main {
    def main(args: Array[String]): Unit = {

    }

    def fac(n: Int) : BigInt = {
        n match {
            case 0 => 1
            case NPlusK(n, 1) => n * fac(n - 1)
        }
    }
}

Scalaでn + kパターンを実装することは可能ですか?その場合はどうすればよいですか?

4

2 に答える 2

4

より長い議論についてはこの質問を見る必要がありますが、ここでは特定のケースに合わせた短い適応があります。

unapplyメソッドは 1 つの引数しかとることができず、その引数からそれを 2 つの部分に分割する方法を決定する必要があります。x = n + kのように整数xnkに分割する方法は複数あるため、これには an を使用できません。unapply

kごとに個別のエクストラクタを作成することで、これを回避できます。したがって、 x = n + 1のようにxからnを取得する方法は 1 つしかないため、 、 などNplusKを使用するNplus1代わりに.Nplus2

case class NplusK(k: Int) {
  def unapply(n: Int) = if (n > 0 && n > k) Some(n - k) else None
}

val Nplus1 = NplusK(1)

val Nplus1(n) = 5  // n = 4

したがって、あなたの試合は次のようになります。

    n match {
        case 0 => 1
        case Nplus1(n) => n * fac(n - 1)
    }
于 2012-05-11T20:46:14.500 に答える
3

Deconstructor unapply は、この方法ではまったく機能しません。1 つの引数 (一致した値) のみを取り、パターン (NPlusK) への引数と同じ数の要素を含むタプルのオプションを返します。つまり、あなたが持っているとき

(n: Int) match {
   ...
   case NPlusK(n, 1)

(またはスーパータイプ) 引数を持つunapplyメソッドを探します。Intそのようなメソッドがあり、戻り値の型が a の場合Tuple2(NPlusK がパターンに 2 つの引数を指定して表示されるため)、一致しようとします。NPlusK 内にあるサブパターン (ここでは変数 n と定数 1) が何であれ、unapply には渡されません (書いたらどうなるでしょうcase NPlusK(NPlusK(1, x), NPlusK(1, y))か?)。代わりに、unapply が何らかのタプルを返す場合、タプルの各要素は対応するサブパターンに一致します。ここnでは常に一致し、値が 1 に等しい場合は 1 に一致します。

あなたは書くことができます

def unapply(n: Int) = if (n > 0) Some((n-1, 1)) else None.  

それはあなたのNPlusK(n, 1). NPlusK(n, 2)しかし、それは, norには一致しませんNPlusK(1, n)(is 2 の場合を除くn)。これはあまり意味がありません。パターンは、おそらく 1 つの一致しか持たないはずです。さまざまな方法でNPlusK(x, y)一致させることができます。n

うまくいくのは、Succ(n)一致するn+1.

于 2012-05-11T20:35:27.363 に答える