2

要するに:私は Scala の DSL のようなものを、型 T の整数 N と A,B のために書こうとしA <N Bています。そうする良い可能性はありますか?

長い: Scala でTGrep2の DSL を書こうとしています。私は現在書くことに興味があります

A <N B          B is the Nth child of A (the rst child is <1).

良い方法で、可能な限り Scala の元の定義に近づけます。<N と B を引数として取ることができる Operatorをオーバーロードする方法はありますか。

私が試したこと:私は2つの異なる可能性を試しましたが、あまり満足できませんでした:

scala> val N = 10
N: Int = 10

scala> case class T(n:String) {def <(i:Int,j:T) = println("huray!")}
defined class T

scala> T("foo").<(N,T("bar"))
huray!

scala> case class T(n:String) {def <(i:Int) = new {def apply(j:T) = println("huray!")}}
defined class T

scala> (T("foo")<N)(T("bar"))
warning: there were 1 feature warnings; re-run with -feature for details
huray!
4

2 に答える 2

3

セマンティクスを明確にするためnthに、シンボルの代わりに次のようなものを使用することをお勧めします。少なくとも私にとっては非常に理にかなっています。それは次のようなものに変換されます<A nth N is B

case class T (label:String){
  def is(j:T) = {
label equals j.label
  }
}

case class J(i:List[T]){
  def nth(index:Int) :T = {
    i(index)
  }
}

あなたは簡単に行うことができます:

val t  = T("Mice")
val t1 = T("Rats")
val j  = J(List(t1,t))

j nth 1 is t //res = true
于 2013-04-02T08:24:34.610 に答える
0

問題はapply、後置演算子として機能しないため、括弧なしでは記述できないことです。次のように記述できます。

  case class T(n: String) {
    def <(in: (Int, T)) = {
      in match {
        case (i, t) =>
          println(s"${t.n} is the ${i} child of ${n}")

      }
    }
  }

  implicit class Param(lower: Int) {
    def apply(t: T) = (lower, t)
  }

しかしその後、

T("foo") < 10 T("bar")

それでも失敗しますが、次の方法で解決できます。

T("foo") < 10 (T("bar"))

どこかに括弧を追加せずに、やりたいことを行う良い方法はありません。

本当にこの構文に固執したい場合は、代わりに組み合わせパーサーを使用することをお勧めします。または、@korefn が提案したように、互換性を壊して新しい演算子を使用します。

于 2013-04-02T14:36:05.927 に答える