Scalaの記号みたいな奴らなんなの
Tags: scala
Published: 2020-04-05 07:50:52

---
title: Scalaの記号みたいな奴らなんなの
published: true
description: Scalaの記号に関するチラシの裏
tags: scala
---

- この記事は 2016年07月03日 にQiitaへ投稿した内容を転記したものです。
- 本記事は執筆から1年以上が経過しています。

# これなんなの？

「Scalaの記号はググラビリティ低すぎて調べようがないし全くわからん…せめて定義位置とか実装がわかれば…」という自分のためのメモ、いわゆるチラシの裏です。

とりあえずScalaの記号については、ソースコードをダウンロードして下記の正規表現でgrepしました。

```
^[^*/]* (?:def|class|object|type|val) ([^0-9A-Za-z" \(\[]+)(?:[ \(\[]|$)
```

基本、わからない記号見つけたら定義元に飛んで ((IntelliJはCtrl+B、EclipseはF3))、ソースを読んでます。（読んで理解できるとは言っていない）

* IDEで定義元に飛べない記号(`_*`など)は、言語仕様の可能性が高いので言語仕様を読みましょう。
* 記号の使用例がわからない場合、そのライブラリのテストコードを読むと良いケースがあります。
* 急に`()`が出てきた場合、カリー化された引数か`apply()`です。  
`apply()`の場合、一時的に書き換えてショートカットキーで飛ぶか、検索して`apply()`の定義を確認します。

https://twitter.com/kmizu/status/724913410962558976

# [Language Specification](http://www.scala-lang.org/files/archive/spec/2.11/)

## バッカス・ナウア記法

Scalaの言語仕様では、文法の定義にバッカス・ナウア記法(BNF: Backus-Naur form)が使用されています。使用されているBNFの記号と意味は下記の通りです。

|記号|意味|
|:-------:|:-----|
|`::=`    |定義|
|`‘…’`    |文字列|
|`` `…'``|文字列|
|&#124;   |OR|
|`( … )`  |グループ化|
|`{ … }`  |0回以上の繰り返し|
|`[ … ]`  |オプション (0回 or 1回)|
|`//`     |コメント (注釈)|
|`“…”`    |コメント (注釈)|

記号ではありませんが、`nl`と`semi`の意味は下記の通りです。

> ```
> nl               ::=  “newlinecharacter”
> semi             ::=  ‘;’ |  nl {nl}
> ```

## Arrow

### Identifiers

#### `⇒` / `←`

http://www.scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#identifiers

> The Unicode operators \u21D2 ‘⇒’ and \u2190 ‘←’, which have the ASCII equivalents => and <-, are also reserved.

なお、2.13.xから非推奨になりました。(実務で使ってる人は皆無だと思いますが…)

> Deprecate unicode arrows `⇒`, `←` and `→` by smarter · Pull Request #7540 · scala/scala
> https://github.com/scala/scala/pull/7540

### Import Clauses

http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#import-clauses

> Import selectors work in the same way for type and term members. For instance, an import clause import p.{x => y} renames the term name p.x to the term name y and the type name p.x to the type name y. At least one of these two names must reference an importable member of p.

`import p.{x => y}`と書くと、`p.x`を`y`という名前でimportすることができます。
`Session`や`Module`等のかぶりやすい名前のtypeを複数importする際に便利なことがあります。

* `java.sql.Date`を`SQLDate`としてimportする例

```scala
import java.util.Date
import java.sql.{Date => SQLDate}
```

> If the target in an import selector is a wildcard, the import selector hides access to the source member. For instance, the import selector x => _ “renames” x to the wildcard symbol (which is unaccessible as a name in user programs), and thereby effectively prevents unqualified access to x. This is useful if there is a final wildcard in the same import selector list, which imports all members not mentioned in previous import selectors.

package内のすべてのtypeをimportする際は`package._`を使用しますが、特定のtypeだけ除外したい場合は`package.{Type => _, _}`と書くことで除外できます。
複数のtypeを除外することもできます。

* `java.util.Date`を除く`java.util._`と`java.sql._`をimportする例

```scala
import java.util.{Date => _, _}
import java.sql._
```

> Scalaスケーラブルプログラミング 第2版
> 13.3 インポート (P.238～239)

### Self type

http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#templates

> ```
ClassTemplate   ::=  [EarlyDefs] ClassParents [TemplateBody]
TraitTemplate   ::=  [EarlyDefs] TraitParents [TemplateBody]
ClassParents    ::=  Constr {`with' AnnotType}
TraitParents    ::=  AnnotType {`with' AnnotType}
TemplateBody    ::=  [nl] `{' [SelfType] TemplateStat {semi TemplateStat} `}'
SelfType        ::=  id [`:' Type] `=>'
                 |   this `:' Type `=>'
```

<!-- -->

> The sequence of template statements may be prefixed with a formal parameter definition and an arrow, e.g. x =>, or x:T =>. If a formal parameter is given, it can be used as an alias for the reference this throughout the body of the template.

class, object, traitの定義部(TemplateBody)の最初に`id : Type =>`または`this : Type =>`と書くことができます。これはSelf Type(自分型)で、基本的に自分自身のインスタンス`this`と同じものを指します。つまり、`this`の別名(alias)を定義することができます。

`id : Type`の型注釈は省略可能で、`id`は慣習的に`self`が使用されます。

#### `self =>`の使用例

Optionでの使用例です。

[Option.scala#L98-L99](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Option.scala#L98-L99)

```scala
sealed abstract class Option[+A] extends Product with Serializable {
  self =>
```

[Option.scala#L197-L211](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Option.scala#L197-L211)

```scala
  /** Necessary to keep $option from being implicitly converted to
   *  [[scala.collection.Iterable]] in `for` comprehensions.
   */
  @inline final def withFilter(p: A => Boolean): WithFilter = new WithFilter(p)

  /** We need a whole WithFilter class to honor the "doesn't create a new
   *  collection" contract even though it seems unlikely to matter much in a
   *  collection with max size 1.
   */
  class WithFilter(p: A => Boolean) {
    def map[B](f: A => B): Option[B] = self filter p map f
    def flatMap[B](f: A => Option[B]): Option[B] = self filter p flatMap f
    def foreach[U](f: A => U): Unit = self filter p foreach f
    def withFilter(q: A => Boolean): WithFilter = new WithFilter(x => p(x) && q(x))
  }
```

`abstract class Option`内で定義した`class WithFilter`から`Option`のインスタンスを参照する際、`this`を使用すると`WithFilter`自身のインスタンスを指してしまいますが、自分型の`self`を使用することで`Option`のインスタンスを参照することができます。

#### `this: Type =>`の使用例

例えば特定のtraitがmixinされていることが前提のクラスに対してmixinするためのtraitを定義するとします。
その際、定義したtrait内でクラスへmixinされているはずのtraitのメンバを使用したいことがあります。

```scala
class SomeClass extends Foo with Bar

trait Foo {
  // ...
}

// Bar は Foo をmixinしているtypeにmixinすることが前提のtrait
trait Bar {
  // Fooのメンバを使用したい…
}
```

その場合は、自分型の`Type`にそのtraitを指定することで、そのtraitのメンバが使用できます。
(thisが`Type`に指定したtypeとして振舞います)

```scala
trait Bar {
  this: Foo =>

  // Fooのメンバが使用できる
}
```

[Play Framework](https://www.playframework.com/)での使用例です。
`Controller`をmixinしているクラスに対してmixinするtraitで、`Controller`のメンバを使用したい場合です。

```scala
import play.api.mvc._

trait FooController {
  this: Controller =>

  // `Controller` のメンバが使用できる
}
```

さらに、`I18nSupport`をmixinしていることが前提の場合は下記のようになります。

```scala
import play.api.i18n.I18nSupport
import play.api.mvc._

trait BarController {
  this: Controller with I18nSupport =>

  // `Controller` と `I18nSupport` のメンバが使用できる
}
```

自分型でtypeを指定した場合、指定したtypeを継承しているtrait, class, objectに対してのみ継承やmixinができます。

```scala
import play.api.mvc._

// OK
class SomeContoller extends Controller with FooController

// Compile error
// illegal inheritance; self-type SomeClass does not conform to FooController's selftype Controller
class SomeClass extends FooController
```

## Atmark

### Pattern Binders

http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#pattern-binders

> A pattern binder x@p consists of a pattern variable x and a pattern p. The type of the variable x is the static type T of the pattern p. This pattern matches any value v matched by the pattern p, provided the run-time type of v is also an instance of T, and it binds the variable name to that value.

パターンマッチングで`x@p`と書くと、パターン`p`に一致した際の値を変数`x`として参照(束縛)することができます。

```scala
List(1, 2, 3) match {
  // headが 1 にマッチするListを変数 x に束縛する
  case x @ 1 :: _ =>
    x // = x: List = List(1, 2, 3)
  case _ =>
    Nil
}
```

> [Scala]パターンマッチにおけるアットマーク(@)
> http://qiita.com/petitviolet/items/89843d948b6fc06eba57

## Colon

### Infix Operations

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#infix-operations

> The associativity of an operator is determined by the operator's last character. Operators ending in a colon `:` are right-associative. All other operators are left-associative.

演算子(operator、メソッド)の最後の文字がコロン(`:`)の場合、その演算子は右被演算子から呼び出されます。(左被演算子は引数になります)

* Seqの例

```scala
val a = Seq(1, 2, 3)

a :+ 4

a.:+(4) // = Seq(1, 2, 3, 4)

// メソッド `+:` は、右被演算子の a から呼び出される
0 +: a

a.+:(0) // = Seq(0, 1, 2, 3)
```

## Unary

### Prefix Operations

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#prefix-operations

> A prefix operation op;e consists of a prefix operator op, which must be one of the identifiers ‘+’, ‘-’, ‘!’ or ‘~’. The expression op;e is equivalent to the postfix method application e.unary_op.

単項(unary)演算子のうち、`+`, `-`, `!`, `~`は前置演算子として使用することができます。前置演算子として使用された場合、`unary_op`メソッドが呼び出されます。

* Booleanの例

```scala
val b = true

// 前置演算子 `!` の場合、`unary_!` メソッドが呼び出される
!b

b.unary_! // = false
```

つまり、`unary_op`メソッドを定義すれば`op`を前置演算子として使用することができます。
メソッド定義の`unary_op`と`:`の間にはスペースが必要です。

```scala
case object Black extends Things
case object White extends Things

sealed abstract class Things {
  def unary_! : Things = {
    this match {
      case Black => White
      case White => Black
    }
  }
}

!Black // = White
```

## Underscore

http://stackoverflow.com/questions/8000903/what-are-all-the-uses-of-an-underscore-in-scala

## `*` / `_*`

### Repeated Parameters

http://www.scala-lang.org/files/archive/spec/2.11/04-basic-declarations-and-definitions.html#repeated-parameters

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#function-applications

* メソッド、関数定義の`Type*`は可変長引数
* 可変長引数は最後の引数でのみ使用できます

```scala
def sum(args: Int*): Int = {
  var result = 0
  for (arg <- args) result += arg
  result
}
```

```scala
val sum: (Int*) => Int = { args =>
  var result = 0
  for (arg <- args) result += arg
  result
}
```

Seq型は`_*`型注釈をつけることで可変長引数に渡すことができます。

```scala
sum(Seq(1, 2, 3, 4): _*)
```

Seq型であればよいので、Seq型に暗黙の型変換されるものでもよいです。

```scala
// Char の可変長引数を取るメソッド
def toHexString(args: Char*): String = {
  args.map(c => f"$c%#06x").mkString(",")
}

// String は WrappedString (Seq[Char]) へ暗黙の型変換されます
toHexString("str": _*)

// 0x0073,0x0074,0x0072
```

### Pattern Sequences

http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#pattern-sequences

Pattern matching中の`_*`はsequence wildcard

```scala
case List(1, 2, _*) => ... // will match all lists starting with 1, 2, ...
```

## `[]`

### 型パラメーター

#### `[A <: B]` `[A >: B]` `[+T]` `[-T]` 

上限・下限境界と変位指定アノテーション

> 第21章：Scalaの型パラメータ
> http://qiita.com/f81@github/items/7a664df8f4b87d86e5d8

> 共変・反変・上限境界・下限境界の関係性まとめ
> http://qiita.com/mtoyoshi/items/bd0ad545935225419327

#### `[_]`

```scala
def f[M[_]]       // Higher kinded type parameter
def f(m: M[_])    // Existential type
```

### `private[C]` / `protected[C]`

http://www.scala-lang.org/files/archive/spec/2.11/05-classes-and-objects.html#modifiers

> A private modifier can be qualified with an identifier C (e.g. private[C]) that must denote a class or package enclosing the definition. Members labeled with such a modifier are accessible respectively only from code inside the package C or only from code inside the class C and its companion module.

<!-- -->

> A protected modifier can be qualified with an identifier C (e.g. protected[C]) that must denote a class or package enclosing the definition. Members labeled with such a modifier are also accessible respectively from all code inside the package C or from all code inside the class C and its companion module.

# Scala Standard Library

## Any

#### [`==`](https://github.com/scala/scala/blob/v2.11.7/src/library-aux/scala/Any.scala#L88)

```scala
  final def ==(that: Any): Boolean = this equals that
```

#### [`!=`](https://github.com/scala/scala/blob/v2.11.7/src/library-aux/scala/Any.scala#L95)

```scala
  final def != (that: Any): Boolean = !(this == that)
```

#### [`##`](https://github.com/scala/scala/blob/v2.11.7/src/library-aux/scala/Any.scala#L107)

```scala
  /** Equivalent to `x.hashCode` except for boxed numeric types and `null`.
   *  For numerics, it returns a hash value which is consistent
   *  with value equality: if two value type instances compare
   *  as true, then ## will produce the same hash value for each
   *  of them.
   *  For `null` returns a hashcode where `null.hashCode` throws a
   *  `NullPointerException`.
   *
   *  @return   a hash value consistent with ==
   */
  final def ##(): Int = sys.error("##")
```

null安全なhashCodeの取得ができます。

```scala
> scala -feature

scala> val s: String = null
s: String = null

scala> s.hashCode
java.lang.NullPointerException
  ... 33 elided

scala> s##
<console>:12: warning: postfix operator ## should be enabled
by making the implicit value scala.language.postfixOps visible.
This can be achieved by adding the import clause 'import scala.language.postfixOps'
or by setting the compiler option -language:postfixOps.
See the Scala docs for value scala.language.postfixOps for a discussion
why the feature should be explicitly enabled.
       s##
        ^
res0: Int = 0
```

[Scalaパズル 36の罠から学ぶベストプラクティス](http://www.shoeisha.co.jp/book/detail/9784798145037)
PUZZLE28　好きな値を選んでください！――Pick a Value, AnyValue! (P.187-189)

## AnyRef

#### [`==`](https://github.com/scala/scala/blob/v2.11.7/src/library-aux/scala/AnyRef.scala#L79-L81)

```scala
  final def ==(that: Any): Boolean =
    if (this eq null) that.asInstanceOf[AnyRef] eq null
    else this equals that
```

null安全な等価比較ができます。

## [library](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/)

### [package.scala](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/package.scala#L61-L69)

```scala
  type ::[A] = scala.collection.immutable.::[A]
  val :: = scala.collection.immutable.::

  val +: = scala.collection.+:
  val :+ = scala.collection.:+

  type Stream[+A] = scala.collection.immutable.Stream[A]
  val Stream = scala.collection.immutable.Stream
  val #:: = scala.collection.immutable.Stream.#::
```

### Numeric value types

http://www.scala-lang.org/files/archive/spec/2.11/12-the-scala-standard-library.html#numeric-value-types

#### Boolean

`==` `!=` `||` `&&` `|` `&` `^`

#### Byte / Char / Short / Int / Long

`<<` `>>` `<<<` `>>>` `==` `!=` `<` `<=` `>` `>=` `|` `&` `^` `+` `-` `*` `/` `%`

#### Float / Double

`==` `!=` `<` `<=` `>` `>=` `|` `&` `^` `+` `-` `*` `/` `%`

### Enumeration

#### [Value](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Enumeration.scala#L201)

```scala
    /** Create a ValueSet which contains this value and another one */
    def + (v: Value) = ValueSet(this, v)
```

#### [ValueSet](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Enumeration.scala#L257-L258)

```scala
    def + (value: Value) = new ValueSet(nnIds + (value.id - bottomId))
    def - (value: Value) = new ValueSet(nnIds - (value.id - bottomId))
```

#### [ValueSet.newBuilder](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Enumeration.scala#L281)

```scala
      def += (x: Value) = { b += (x.id - bottomId); this }
```

## [Predef.scala](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Predef.scala)

http://www.scala-lang.org/files/archive/spec/2.11/12-the-scala-standard-library.html#the-predef-object

#### [`???`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Predef.scala#L222-L225)

```scala
  /** `???` can be used for marking methods that remain to be implemented.
   *  @throws NotImplementedError
   */
  def ??? : Nothing = throw new NotImplementedError
```

#### [ArrowAssoc](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Predef.scala#L247-L250)

```scala
  implicit final class ArrowAssoc[A](private val self: A) extends AnyVal {
    @inline def -> [B](y: B): Tuple2[A, B] = Tuple2(self, y)
    def →[B](y: B): Tuple2[A, B] = ->(y)
  }
```

`a -> b`と書くと`Tuple2(a, b)`に変換されて不思議に思ったことありませんか？これです。

#### [`<:<`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Predef.scala#L383)

> An instance of `A <:< B` witnesses that `A` is a subtype of `B`.

<!-- -->

> <:<を使ってメソッド引数の型を限定する (例: IntもしくはBooleanもしくはString
> http://qiita.com/mtoyoshi/items/fbf2c744e3c7fd69a438

> 続<:<を使ってメソッド引数の型を限定する（厳密に）
> http://qiita.com/mtoyoshi/items/13ac0500aa23fb4fa0d4

#### [`=:=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/Predef.scala#L398)

> An instance of `A =:= B` witnesses that the types `A` and `B` are equal.

## collections

### Traversable

#### TraversableLike

[`++`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/TraversableLike.scala#L154) コレクションを追加した新しいコレクションを返す
[`++:`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/TraversableLike.scala#L194) 右辺のコレクションと左辺のコレクションを追加した新しいコレクションを返す

```scala
Seq(1, 2, 3) ++ Seq(4, 5, 6)  // = Seq(1, 2, 3, 4, 5, 6)

Seq(1, 2, 3) ++: Seq(4, 5, 6) // = Seq(1, 2, 3, 4, 5, 6)
```

#### [TraversableOnce](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/TraversableOnce.scala#L149-L151)

```scala
  def /:[B](z: B)(op: (B, A) => B): B = foldLeft(z)(op)

  def :\[B](z: B)(op: (A, B) => B): B = foldRight(z)(op)
```

### SeqLike

[`+:`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/SeqLike.scala#L548-L553) 要素にSeqを追加した新しいSeqを返す (Seqの先頭に要素を挿入した新しいSeqを返す)
[`:+`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/SeqLike.scala#L555-L560) Seqに要素を追加した新しいSeqを返す

```scala
0 +: Seq(1, 2, 3) // = Seq(0, 1, 2, 3)

Seq(1, 2, 3) :+ 4 // = Seq(1, 2, 3, 4)
```

### generic

#### Growable

http://www.scala-lang.org/api/2.11.7/index.html#scala.collection.generic.Growable

mutableなコレクションなどにmixinされているtrait
新しいコレクションを作らず、コレクションに直接要素を追加する

[`+=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/generic/Growable.scala#L29-L43) コレクションへ1つ、または複数の要素を追加する
[`++=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/generic/Growable.scala#L50) 引数のコレクションにある要素を追加する

#### Shrinkable

http://www.scala-lang.org/api/2.11.7/index.html#scala.collection.generic.Shrinkable

mutableなコレクションなどにmixinされているtrait
新しいコレクションを作らず、コレクションから直接要素を削除する

[`-=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/generic/Shrinkable.scala#L24-L42) コレクションから1つ、または複数の要素を削除する
[`--=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/generic/Shrinkable.scala#L49) 引数のコレクションにある要素を削除する

#### Subtractable

http://www.scala-lang.org/api/2.11.7/index.html#scala.collection.generic.Subtractable

[`-`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/generic/Subtractable.scala#L32-L51) コレクションから1つ、または複数の要素を削除した新しいコレクションを返す

`override def -`でソースコードを検索すると、コレクション毎の実装詳細を確認することができます。

[`--`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/generic/Subtractable.scala#L60)

```scala
  def --(xs: GenTraversableOnce[A]): Repr = (repr /: xs.seq) (_ - _)
```

引数のコレクションにある要素を削除した新しいコレクションを返す

### BitSetLike

[`|`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/BitSetLike.scala#L143) [`&`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/BitSetLike.scala#L157) [`&~`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/BitSetLike.scala#L172) [`^`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/BitSetLike.scala#L187)

BitSet同士のor, and, and-not, xorを取り、新しいBitSetを返す

### mutable.BitSet

[`|=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/mutable/BitSet.scala#L112) [`&=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/mutable/BitSet.scala#L123) [`&~=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/mutable/BitSet.scala#L147) [`^=`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/mutable/BitSet.scala#L136)

BitSet同士のor, and, and-not, xorを取り、BitSetを更新する

### GenSetLike

#### [`+`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/GenSetLike.scala#L33) [`-`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/GenSetLike.scala#L34)

```scala
  def +(elem: A): Repr
  def -(elem: A): Repr
```

Setへ要素を追加、削除する

#### [`&`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/GenSetLike.scala#L61)

```scala
  def &(that: GenSet[A]): Repr = this intersect that
```

Set同士のandを取る

#### [`|`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/GenSetLike.scala#L78)

```scala
  def | (that: GenSet[A]): Repr = this union that
```

Set同士のorを取る

#### [`&~`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/GenSetLike.scala#L95)

```scala
  def &~(that: GenSet[A]): Repr = this diff that
```

Set同士のand-notを取る ((本来、要素の順序は保証されませんが、わかりやすさのためソートして書いています))

```scala
val a = Set(1, 2, 3, 4, 5, 6)
val b = Set(1, 2, 3)

a &~ b // = Set(4, 5, 6)

b &~ a // = Set()
```

### [immutable.::](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/List.scala#L439-L442)

```scala
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
  override def tail : List[B] = tl
  override def isEmpty: Boolean = false
}
```

`::(head, tail)`となるようなListを返すクラスです。

[package.scala](#package.scala)で`::`のtype aliasが定義されており、Listに対するパターンマッチ(`case head :: tail`)でも使用されます。

余談ですが、REPLでは`:`から始まる文字列がコマンドとして解釈されるため、バッククォートで囲みリテラル識別子(literal identifiers)にする必要があります。

```scala
scala> `::`(1, List(2, 3, 4))
res0: scala.collection.immutable.::[Int] = List(1, 2, 3, 4)

scala> res0.head
res1: Int = 1

scala> res0.tail
res2: List[Int] = List(2, 3, 4)
```

### immutable.List

#### [`::`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/List.scala#L111-L112)

```scala
  def ::[B >: A] (x: B): List[B] =
    new scala.collection.immutable.::(x, this)
```

メソッドの最後の文字が`:`なので、right-associativeです。
Scaladocのexampleに書かれていますが、下記のようになります。

`1 :: List(2, 3)` = `List(2, 3).::(1)` = `List(1, 2, 3)`

つまり、終端がListであればよいので、`Nil`も使えます。

```scala
1 :: 2 :: 3 :: Nil

1 :: 2 :: Nil.::(3)

1 :: 2 :: List(3)

1 :: List(3).::(2)

1 :: List(2, 3)

List(2, 3).::(1)

List(1, 2, 3)
```

#### [`:::`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/List.scala#L125-L128)

```scala
  def :::[B >: A](prefix: List[B]): List[B] =
    if (isEmpty) prefix
    else if (prefix.isEmpty) this
    else (new ListBuffer[B] ++= prefix).prependToList(this)
```

List同士を連結した新しいListを返す

```scala
List(1, 2, 3) ::: List(4, 5, 6) // = List(1, 2, 3, 4, 5, 6)
```

### [Stream.#::](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/Stream.scala#L1201-L1205)

```scala
  object #:: {
    def unapply[A](xs: Stream[A]): Option[(A, Stream[A])] =
      if (xs.isEmpty) None
      else Some((xs.head, xs.tail))
  }
```

Streamのパターンマッチ(`case head #:: tail`)のために定義されている記号(object)
[package.scala](#package.scala)に`#::`のtype aliasが定義されています。

### Stream.ConsWrapper

`#::`と`#:::`が定義されていて、Streamからこれらのメソッドが呼ばれるとConsWrapperに暗黙の型変換が行われます。

```scala
  /** A wrapper method that adds `#::` for cons and `#:::` for concat as operations
   *  to streams.
   */
  implicit def consWrapper[A](stream: => Stream[A]): ConsWrapper[A] =
    new ConsWrapper[A](stream)
```

#### [#::](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/Stream.scala#L1186)

```scala
  def #::(hd: A): Stream[A] = cons(hd, tl)
```

簡単にいうと、`head #:: tail`となるようなStreamが返ります。

実際には`object cons`の`apply()`が実行され、`final class Cons[+A](hd: A, tl: => Stream[A]) extends Stream[A]`が返ります。

#### [#:::](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/Stream.scala#L1190)

```scala
  def #:::(prefix: Stream[A]): Stream[A] = prefix append tl
```

Stream同士を連結した新しいStreamを返す

### mutable.BufferLike

#### [`++=:`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/mutable/BufferLike.scala#L137)

```scala
  def ++=:(xs: TraversableOnce[A]): this.type = { insertAll(0, xs.toTraversable); this }
```

コレクション`xs`を現在のBufferの前方に挿入する

```scala
val buffer = mutable.Buffer(4, 5, 6)

Seq(1, 2, 3) ++=: buffer

buffer // = mutable.Buffer(1, 2, 3, 4, 5, 6)
```

### StringLike

#### [`*`](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/collection/immutable/StringLike.scala#L68-L72)

```scala
  def * (n: Int): String = {
    val buf = new StringBuilder
    for (i <- 0 until n) buf append toString
    buf.toString
  }
```

現在の文字列を指定回数連結した文字列を返す

## math

`/%`: 商と余りをTupleで返す
`&~`: and-not (this & ~that)

#### BigDecimal

`<=` `>=` `<` `>` `+` `-` `*` `/` `/%` `%`

#### BigInt

`<=` `>=` `<` `>` `+` `-` `*` `/` `%` `/%` `<<` `>>` `&` `|` `^` `&~`

#### [Fractional](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/math/Fractional.scala#L21)

`/`

#### [Integral](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/math/Integral.scala#L24-L26)

`/` `%` `/%`

#### [Numeric](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/math/Numeric.scala#L215-L217)

`+` `-` `*`

#### [Ordered](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/math/Ordered.scala#L74-L88)

`<` `>` `<=` `>=`

#### [Ordering](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/math/Ordering.scala#L127-L130)

`<` `<=` `>` `>=`

#### [PartiallyOrdered](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/math/PartiallyOrdered.scala#L30-L49)

`<` `>` `<=` `>=`

## sys

#### [SystemProperties](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/SystemProperties.scala#L45-L46)

`-=` `+=`

#### [package process](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/process/package.scala#L227)

```scala
type =?>[-A, +B]     = PartialFunction[A, B]
```
#### [ProcessBuilder (extends Source with Sink)](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/process/ProcessBuilder.scala#L141)

http://www.scala-lang.org/api/2.11.x/#scala.sys.process.ProcessBuilder

| 記号 | 機能 |
|:------------|:--|
|!!           |blocks until all external commands exit, and returns a String with the output generated.|
|!!<          |stdin + `!!`|
|!            |blocks until all external commands exit, and returns the exit code of the last one in the chain of execution.|
|!<           |stdin + `!`|
|#&#124;      |pipe (Shellの &#124; )|
|###          |コマンドが終了後、後続のコマンドを実行。|
|#&&          |コマンドのexit codeが0の時、後続のコマンドを実行。 (Shellの && )|
|#&#124;&#124;|コマンドのexit codeが0以外の時、後続のコマンドを実行　(Shellの &#124;&#124; )|

#### [FileBuilder (extends Sink with Source)](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/process/ProcessBuilder.scala#L311-L321)

`#<<`

#### [Source](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/process/ProcessBuilder.scala#L330-L343)

| 記号 | 意味 |
|:------------|:--|
|`#>`         |Redirect stdout (overwrite)|
|`#>>`        |Redirect stdout (append)|

#### [Sink](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/process/ProcessBuilder.scala#L356-L369)

| 記号 | 意味 |
|:------------|:--|
|`#<`         |Redirect stdin|

#### [AbstractBuilder (extends ProcessBuilder with Sink with Source)](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/process/ProcessBuilderImpl.scala#L85)

`!!` `!!<` `!` `!<` `#|` `###` `#&&` `#||`

#### [FileImpl (extends FileBuilder with Sink with Source)](https://github.com/scala/scala/blob/v2.11.7/src/library/scala/sys/process/ProcessBuilderImpl.scala#L161-L164)

`#<<`

# ex-Scala Standard Library

以下のライブラリは2.11.0で標準ライブラリから分離されました。

* [scala.util.parsing.combinator](https://github.com/scala/scala-parser-combinators)
* [scala.xml](https://github.com/scala/scala-xml)
* [scala.util.continuationsScala](https://github.com/scala/scala-continuations)

> Scala 2.11.0で標準ライブラリから分離されたライブラリのjarファイル - kmizuの日記
> http://kmizu.hatenablog.com/entry/2014/04/24/005958

<!--
## scala-parser-combinators

### [scala.util.parsing.combinator.Parsers](https://github.com/scala/scala-parser-combinators/blob/v1.0.3/src/main/scala/scala/util/parsing/combinator/Parsers.scala)

`^^`
`^^^`
`^?`
`*`
`+`
`?`

> 面倒くさいパーサの実装もDSLで書くだけ！そう、Scalaならね
> http://qiita.com/suin/items/35bc4afe618cb77f80f6

> Scala: パーサコンビネータの | と ^^ の組み合わせは注意
> http://qiita.com/suin/items/48899a38af75ac358939

### [scala.util.parsing.input.Position](https://github.com/scala/scala-parser-combinators/blob/v1.0.3/src/main/scala/scala/util/parsing/input/Position.scala)

#### [`<`](https://github.com/scala/scala-parser-combinators/blob/v1.0.3/src/main/scala/scala/util/parsing/input/Position.scala#L58-L61)

```scala
  def <(that: Position) = {
    this.line < that.line ||
    this.line == that.line && this.column < that.column
  }
```

Positionの比較を行う
-->

## scala-xml

Lexical Syntax - 1.5 XML mode
http://www.scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#xml-mode

XML Expressions and Patterns
http://www.scala-lang.org/files/archive/spec/2.11/10-xml-expressions-and-patterns.html

### [XML expressions](http://www.scala-lang.org/files/archive/spec/2.11/10-xml-expressions-and-patterns.html#xml-expressions)

ScalaはXML(XMLリテラル)を直接扱うことができます。ただし、前述のとおりscala.xmlが標準ライブラリから外されたため、クラスパスに追加しないとコンパイルできません。 ((REPLはscala.xmlパッケージが含まれているため、そのまま使用することができます))

```scala
val a = <a>text</a> // = a: scala.xml.Elem = <a>text</a>
```

> XML expressions may contain Scala expressions as attribute values or within nodes. In the latter case, these are embedded using a single opening brace { and ended by a closing brace }. To express a single opening braces within XML text as generated by CharData, it must be doubled. Thus, {% raw %}{{{% endraw %} represents the XML text { and does not introduce an embedded Scala expression.

XMLでScalaの変数や式を参照する場合は`{}`を使用します。
参照ではなく単純に波括弧を使用したい場合は`{{`や`}}`を使用します。

```scala
<a>{brace}</a>   // error: not found: value brace
<a>{{brace}}</a> // <a>{brace}</a>

val text = "text value"

<a>{text}</a>         // = <a>text value</a>
<a>{{text</a>         // = <a>{text</a>
<a>text}}</a>         // = <a>text}</a>

<a>{{{text}}}</a>     // = <a>{text value}</a>
<a>{{{{text}}}}</a>   // = <a>{{text}}</a>
<a>{{{{{text}}}}}</a> // = <a>{{text value}}</a>
```

単純に`{{`の組み合わせが、XML textの`{`に変換されています。

### [XML patterns](http://www.scala-lang.org/files/archive/spec/2.11/10-xml-expressions-and-patterns.html#xml-patterns)

XMLリテラルはそのままパターンマッチングで使用することができます。
パターンマッチングの`{}`内では[Scalaのパターンマッチ](http://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html#pattern-matching-expressions)が使用できます。

```scala
// 変数パターンによるマッチング
<a><b>text</b></a> match {
  case <a>{value}</a> => println(value)
  case _ => println("unmatched")
}

// <b>text</b>

<a><b>bold</b> text</a> match {
  case <a>{value}</a> => println(value)
  case _ => println("unmatched")
}

// unmatched
```

任意のXMLノードシーケンスにマッチさせるためには、[Pattern Sequences](#pattern-sequences)(`_*`)を使用する必要があります。
(2つ目の`<a>`には`<b>`と` text`の2つのノードが含まれていました)

```scala
// Pattern Sequencesによるマッチング
val list = <ul type="circle">
             <li>a</li>
             <li>b</li>
             <li>c</li>
           </ul>

list match {
  case <ul>{items @ _*}</ul> =>
    for (item <- items) {
      println(s"item: $item")
    }
}

// item: 
//                
// item: <li>a</li>
// item: 
//                
// item: <li>b</li>
// item: 
//                
// item: <li>c</li>
// item: 
//              
```

XMLでは改行や空白もTextノードなのでパターンに一致します。
[for式](http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#for-comprehensions-and-for-loops)のGeneratorでは```Pattern `<-' Expr```でパターンマッチングが使用できるので、これで必要なノードのみ抽出できます。

```scala
val list = <ul type="circle">
             <li>a</li>
             <li>b</li>
             <li>c</li>
           </ul>

list match {
  case <ul>{items @ _*}</ul> =>
    for (item @ <li>{_*}</li> <- items) {
      println(s"item: $item")
    }
}

// item: <li>a</li>
// item: <li>b</li>
// item: <li>c</li>
```

> Scalaスケーラブルプログラミング 第2版
> 28.8 XMLを対象とするパターンマッチ (P.566～569)

### Atom

https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/Atom.scala

記号とは直接関係ありませんが、この後`new Atom()`や`_.isAtom`が出てくるため簡単に説明します。
Atomはlabelが`#PCDATA` ((PCDATA: Parsed Character Data)) であるTextノードです。

例えば、[XML patterns](#xml-patterns)のサンプルコードで一致した改行や空白のTextノードは、`isAtom`で`true`を返します。

### Elem

#### [`%`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/Elem.scala#L121-L122)

```scala
  final def %(updates: MetaData): Elem =
    copy(attributes = MetaData.update(attributes, scope, updates))
```

指定されたattributes(MetaData)に更新した新しいElemを返す

### NodeBuffer

#### [`&+`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/NodeBuffer.scala#L36-L46)

```scala
  def &+(o: Any): NodeBuffer = {
    o match {
      case null | _: Unit | Text("") => // ignore
      case it: Iterator[_]           => it foreach &+
      case n: Node                   => super.+=(n)
      case ns: Iterable[_]           => this &+ ns.iterator
      case ns: Array[_]              => this &+ ns.iterator
      case d                         => super.+=(new Atom(d))
    }
    this
  }
```

下記のような処理になっています。

* `Iterable`や`Array`のようなコレクションは`iterator.foreach`で要素個別に処理
* `Node`であればそのまま追加、それ以外は`Atom`(Textノード)として追加
* `null`、`Unit`、空文字の`Text`は無視

### NodeSeq

XPathに`/`や`//`がありますが、Scalaで`//`はコメント行として使用されるため、NodeSeqの記号ではバックスラッシュの`\`や`\\`が使用されています。
(Scalaスケーラブルプログラミング 第2版 P.564より)

#### [`\`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/NodeSeq.scala#L96-L125)

自身のノードを基準として条件に一致するノードを抽出します。
多機能なのでScaladocを引用すると下記のようになります。

> - `this \ "foo"` to get a list of all elements that are labelled with `"foo"`;
> - `\ "_"` to get a list of all elements (wildcard);
> - `ns \ "@foo"` to get the unprefixed attribute `"foo"`;
> - `ns \ "@{uri}foo"` to get the prefixed attribute `"pre:foo"` whose
>    prefix `"pre"` is resolved to the namespace `"uri"`.

* `this \ "foo"`

直下の子ノードで要素名(label)に一致するノードを返します。
XPathの`node/foo`に相当します。

* `this \ "_"`

直下の子ノードでAtom以外のノードすべてを返します。(ワイルドカード)
XPathの`node/*`に相当します。

* `ns \ "@foo"`

自身のノードから一致する属性名の値を返します。
XPathの`node/@attribute`に相当します。

ただし、自身が単一のノード(`this.length == 1`)である必要があります。
複数のノードの場合、空の`NodeSeq`を返します。

```c
// 単一のノード
<a href="http://qiita.com/">Qiita</a> \ "@href" // = scala.xml.NodeSeq = http://qiita.com/

// 複数のノード
<a href="http://qiita.com/">Qiita</a>
<a href="https://teams.qiita.com/">Qiita:Team</a> \ "@href" // = scala.xml.NodeSeq = NodeSeq()
```

* `ns \ "@{uri}foo"`

名前空間プレフィックスのついた属性名(`prefix:attribute`)の値を返します。
[Mavenのpom.xml](https://maven.apache.org/pom.html#Quick_Overview)を例にすると下記のようになります。

```scala
val project =
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/xsd/maven-4.0.0.xsd"></project>

// "xsi:schemaLocation"の値を取得
project \ "@{http://www.w3.org/2001/XMLSchema-instance}schemaLocation"

// = scala.xml.NodeSeq =
// http://maven.apache.org/POM/4.0.0
//                       http://maven.apache.org/xsd/maven-4.0.0.xsd
```

#### [`\\`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/NodeSeq.scala#L143-L150)

XPathの`//`に相当し、すべての子孫ノードを対象に抽出を行います。

#### [`\@`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/NodeSeq.scala#L156)

```scala
  def \@(attributeName: String): String = (this \ ("@" + attributeName)).text
```

Nodeの指定した属性名の値を取得する
(`\ "@attributeName"`と動作は等価ですが、戻り値はString型です)

### CachedFileStorage

#### [`+=`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/persistent/CachedFileStorage.scala#L70-L71)

```scala
  /** adds a node, setting this.dirty to true as a side effect */
  def +=(e: Node): Unit
```

#### [`-=`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/persistent/CachedFileStorage.scala#L73-L74)

```scala
  /** removes a tree, setting this.dirty to true as a side effect */
  def -=(e: Node): Unit
```

### SetStorage (extends CachedFileStorage)

#### [`+=`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/persistent/SetStorage.scala#L36)

```scala
  def +=(e: Node): Unit = synchronized { this.dirty = true; theSet += e }
```

#### [`-=`](https://github.com/scala/scala-xml/blob/v1.0.5/src/main/scala/scala/xml/persistent/SetStorage.scala#L38)

```scala
  def -=(e: Node): Unit = synchronized { this.dirty = true; theSet -= e }
```