2013-06-13 3 views
9

http://woss.name/2012/04/02/retrieving-bigdecimals-from-a-database-with-anorm-scala/このScalaの例でチルダ(〜)は何を意味していますか?

object Site { 
    val allFieldsParser = { 
    get[Pk[Long]]("sites.id") ~  // Help me parse this syntax 
    get[String]("sites.name") ~ 
    get[BigDecimal]("sites.latitude") ~ 
    get[BigDecimal]("sites.longitude") map { 
     case id ~ name ~ latitude ~ longitude => 
     Site(id, name, latitude, longitude) 
    } 
    } 

    def findAll(): Seq[Site] = { 
    DB.withConnection { implicit connection => 
     SQL("SELECT * FROM sites").as(Site.allFieldsParser *) 
    } 
    } 
} 
+2

この表記はパーサーコンビネータから得られたものです。つまり、http://stackoverflow.com/questions/6818390/understanding-the-tilde-in-scalas-parser-combinatorsを見てください。つまり、あなたは精神的に '〜'を '&'に置き換えることができます。そのような構造はパターン(あなたは、正規表現のパターンのように知っています)。あなたは、特定のパーツを使用して高レベルの表現を定義しています(〜のソリッド構造に結合されています)。そして、パーサーのいずれかが成功し、あなたのスキームに従って構造が得られないか、失敗します。例えば、代数式を照合するには 'Number〜Operation〜Number ...のようなものを書くことができます' –

+0

@ om-nom-nomだから、なぜあなたはコメントで答えましたか? –

+1

@ DanielC.Sobral私は質問が技術的な実装(すでにgzm0によって説明されていたかどうか)または意味論的なものかどうかは不明です。 –

答えて

21

あなたの例では、〜は、二つの異なるものを意味する2つの異なる方法で使用されています。すでに、これは単なるメソッド呼び出しで、指摘されているとして、あなたは

get[Pk[Long]]("sites.id") ~  // Help me parse this syntax 
get[String]("sites.name") ~ 
get[BigDecimal]("sites.latitude") ~ 

などを持っている最初の部分では、それはあなたがthe definition of this method in the anorm sourceで見ることができ

get[Pk[Long]]("sites.id").~(get[String]("sites.name").~(... 

と同じです。なお、このA ~ B~ための第2の意味である。Bを解析RowParser[B](パーサ)をとり、A ~ Bを解析するパーサを返しAを解析RowParser[A](パーサ、上の方法である。これは、今ではない言及しています方法に、しかしcase class defined in the same file here.

case class ~[+A, +B](_1: A, _2: B) 

にこれはクラス~[A,B]を参照するだけの特有な方法です。型レベルでは、次の2つの引数の型コンストラクタを持っているとき、あなたはの名前を使用することができますこれは、~について特別なものではなく、任意の2つで動作します引数型コンストラクタtrait Foo[A,B]がある場合は、それをA Foo Bと呼ぶことができます。同様に、のパターンマッチングでは、変数abは、language specificationのセクション8.1.10のインフィニクス操作パターンと呼ばれる構文a Foo bを使用してバインドできます。あなたが持っているあなたの例の第二部で

case id ~ name ~ latitude ~ longitude => 

これは上記のように構成解析を実行した結果であるこれら~ケースclasesにパターンマッチングです。だからこれは本当にちょうど良い方法です:

case ~(~(~(id, name), latitude), longitude) => 
+0

徹底的な答えをありがとう。 – ripper234

5
Scalaの

a ~ b 

だから、a上のメソッド~を呼び出し、引数として与えb

a.~(b) 

を意味します。また、:で終わらないオペレータは左結合であることに注意してください。

あなたの例は、再訪は、次のようになります。

get[Pk[Long]]("sites.id").~( // Help me parse this syntax 
get[String]("sites.name").~(
get[BigDecimal]("sites.latitude").~(
get[BigDecimal]("sites.longitude")))) map { 
    case id ~ name ~ latitude ~ longitude => 
    Site(id, name, latitude, longitude) 
} 
+1

より一般的には、 'a whatever b 'は' a.whatever(b) 'を意味します(いくつかのキーワード、プリミティブ演算子、あなたがすでに言及した左結合インジケータを除く)。 –