約 2,681,178 件
https://w.atwiki.jp/scala-lang/pages/13.html
Scala 主要なライブラリ Scalaz Shapeless
https://w.atwiki.jp/kojiro/pages/591.html
SCALE
https://w.atwiki.jp/anddoid/pages/69.html
scale 関連タグ 使用例
https://w.atwiki.jp/konaasobi/pages/54.html
拡大(SCALE) 1,2,4,8,16倍率と変更可能。 細かい作業等には非常に便利である。 右クリックと左クリックでは 少しズレがある。
https://w.atwiki.jp/hmiku/pages/62187.html
【検索用 scale 登録タグ 2011年 S UTAU nwnw みなと 曲 曲英 水音ラル】 + 目次 目次 曲紹介 歌詞 コメント 作詞:みなと 作曲:nwnw 編曲:nwnw 唄:水音ラル(調声:みなと) 曲紹介 曲名:『scale』 歌詞 Ah.. 尺はかり 積み上げる つりあわない 聴く言葉 くずれてく 広がりはくずれる 明日まで続くこの道と それを拒否する この 感情 それを受け入れ難く 積りゆくこの感覚 はかられる その法則は 受け入れる こともない つみあげていく 飽和した 音、声。 彼たちは 留まる。 溜まる、、 広がる景色の感情 それは僕には大きすぎた それは、広がり続け、 とても素晴らしく輝くのだ コメント 名前 コメント コメントを書き込む際の注意 コメント欄は匿名で使用できる性質上、荒れやすいので、 以下の条件に該当するようなコメントは削除されることがあります。 コメントする際は、絶対に目を通してください。 暴力的、または卑猥な表現・差別用語(Wiki利用者に著しく不快感を与えるような表現) 特定の個人・団体の宣伝または批判 (曲紹介ページにおいて)歌詞の独自解釈を展開するコメント、いわゆる“解釈コメ” 長すぎるコメント 『歌ってみた』系動画や、歌い手に関する話題 「カラオケで歌えた」「学校で流れた」などの曲に直接関係しない、本来日記に書くようなコメント カラオケ化、カラオケ配信等の話題 同一人物によると判断される連続・大量コメント Wikiの保守管理は有志によって行われています。 Wikiを気持ちよく利用するためにも、上記の注意事項は守って頂くようにお願いします。
https://w.atwiki.jp/dustgame2/pages/58.html
概要 画面を拡大/縮小できる操作。 ×1、×2、×4、×8、×16の五段階に調節できる。標準はもちろん×1。 拡大した画面はドラッグで動かすことができる。 細かい作業の際に役に立つ。SAVEではSCALEは保存されないので注意が必要。 コメント欄 名前 コメント すべてのコメントを見る
https://w.atwiki.jp/tmiya/pages/125.html
Scala ひと巡り (A Tour of Scala) 原ページ Published on The Scala Programming Language (http //www.scala-lang.org) . By admin . Created 2008-07-05, 20 31 Scala は簡潔でエレガント、そして型安全な方法で共通のプログラミングパターンを表現できるよう設計された現代的なマルチパラダイム・プログラミング言語です。 オブジェクト指向の特徴と関数型言語の特質をスムーズに統合します。 Scala はオブジェクト指向言語です すべての値がオブジェクトである [1]という意味で、Scala は純粋なオブジェクト指向言語です。オブジェクトの型と振る舞いをクラス [2]とトレイト [3]によって記述します。 クラスはサブクラス化 [4]と、多重継承の欠点のない置換えである、柔軟なミックスインベースの合成 [5]メカニズムにより拡張されます。 Scala は関数型言語です すべての関数が値である[1]という意味で、Scala は関数型言語でもあります。 Scala は無名関数の定義に簡単な構文 [6]を提供します。それは高階関数 [7]をサポートし、関数のネストを可能とし[8]、カリー化 [9]をサポートします。 Scala のケースクラス [10]とパターンマッチィング [11]の組み込みサポートは、多くの関数型プログラミング言語で使われる代数型をモデル化します。 Furthermore, Scala's notion of pattern matching naturally extends to the processing of XML data [12] with the help of right-ignoring sequence patterns [13]. In this context, sequence comprehensions [14] are useful for formulating queries. さらに、Scala のパターンマッチィングの概念は、右無視シーケンスパターン(right-ignoring sequence pattern) [13]の助けにより、XML データ [12]の処理へ自然に拡張されます。このコンテキストにおいて、シーケンス内包表記(sequence comprehensions) [14]はクエリの定式化に対して役立ちます。 これらの特徴により Scala は、Web サービス[15]のようなアプリケーション開発に理想的なものとなっています。 Scala は静的な型付け言語です Scala は、抽象化が安全で理路整然とした方法でなされることを静的に強制する、表現力豊かな型システムを備えています。 特に、型システムは次をサポートします。 ジェネリッククラス (generic classes [16]) 変位指定アノテーション (variance annotations [17]) 上/下限 型境界 (upper[18] and lower[19] type bounds) 内部クラスとオブジェクトメンバーとしての抽象型 (inner classes [20] and abstract types [21] as object members) 複合型 (compound types [22]) 明示的に型付けされた自己参照 (explicitly typed self references [23]) ビュー (view [24]) 多相的メソッド (polymorphic methods [25]) ローカルな型推論 [26]機構により、ユーザーはプログラムに冗長な型情報で注釈を付ける必要がありません。 これらフィーチャーの組み合わせは、プログラミング抽象の安全な再利用とソフトウェアの型安全な拡張に対して、強力な基盤を提供します。 Scala は拡張性に富んでいます 現場では、固有領域のアプリケーション開発はしばしば領域固有の言語拡張を必要とします。Scala は、新たな言語要素をライブラリの形でスムーズに容易に加えることができる言語メカニズムのユニークな組合せを提供します どのようなメソッドも中置あるいは後置演算子 [27]として使うことができます。そして 要請型(expected type 期待される型)に応じて、クロージャが自動的に構成されます[28](target typing ターゲットによる型付け)。 両フィーチャーの共同使用は、構文拡張なしの、またマクロのようなメタプログラミングファシリティの助けを借りない、新しい文定義を促進します。 Scala は Java や .NET と相互運用できます Scala は、ポピュラーな Java 2 実行環境(JRE [29])とうまく相互運用できるように設計されています。 特に、主流のオブジェクト指向 Java プログラミング言語との相互作用は可能な限りスムーズです。 Scala は、Java と同列のコンパイルモデル(ダイナミックなクラスローディング、分割コンパイル)を採用しており、既存の何千もの高品質ライブラリにアクセスできます。 .NET フレームワーク(CLR [30])のサポートも同様に利用できます。 さらに次のページをお読みください。 Scala ひと巡り 抽象型 (Abstract Types) Scala ひと巡り アノテーション (Annotations) Scala ひと巡り クラス (Classes) Scala ひと巡り ケースクラス (Case Classes) Scala ひと巡り 事前定義された classOf 関数 (Predefined function classOf) Scala ひと巡り 複合型 (Compound Types) Scala ひと巡り シーケンス内包表記 (Sequence Comprehensions) Scala ひと巡り 抽出子オブジェクト (Extractor Objects) Scala ひと巡り ジェネリッククラス (Generic Classes) Scala ひと巡り 暗黙のパラメータ (Implicit Parameters) Scala ひと巡り 内部クラス (Inner Classes) Scala ひと巡り ミックスインクラス合成 (Mixin Class Composition) Scala ひと巡り 関数のネスト (Nested Functions) Scala ひと巡り 無名関数の構文 (Anonymous Function Syntax) Scala ひと巡り カリー化 (Currying) link_anchor plugin error 画像もしくは文字列を必ずどちらかを入力してください。{ Scala ひと巡り 型依存クロージャの自動構築 (Automatic Type- link_anchor plugin error idが指定されていないか、存在しないページを指定しています。 Scala ひと巡り オペレータ (Operators) Scala ひと巡り 高階関数 (Higher-Order Functions) Scala ひと巡り パッケージ (Packages) Scala ひと巡り パターンマッチィング (Pattern matching) Scala ひと巡り 多相的メソッド (Polymorphic Methods) Scala ひと巡り 正規表現パターン (Regular Expression Patterns) Scala ひと巡り sealed クラス (Sealed Classes) Scala ひと巡り トレイト (Traits) Scala ひと巡り 上限 型境界 (Upper Type Bounds) Scala ひと巡り 下限 型境界 (Lower Type Bounds) Scala ひと巡り 明示的に型付けられた自己参照 (Explicitly Typed Self References) Scala ひと巡り サブクラス化 (Subclassing) Scala ひと巡り ローカルな型推論 (Local Type Inference) Scala ひと巡り 統一された型 (Unified Types) Scala ひと巡り 変位指定 (Variances) Scala ひと巡り ビュー (Views) Scala ひと巡り XML 処理 (XML Processing) Scala ひと巡り 抽象型 (Abstract Types) 原ページ Scala では、クラスは値(コンストラクタ・パラメータ)と(もしクラスがジェネリック [16]なら)型でパラメータ化されます。 単に規則に従って、オブジェクトメンバーとして値を持てるというばかりではありません; 値と共に、型はオブジェクトのメンバーです。 さらに、メンバーの両形式とも、具象あるいは抽象で構いません。 次の例は、クラス Buffer のメンバーとして、延期された値定義と抽象型定義の両方を定義しています。 abstract class Buffer { type T val element T } 抽象型はその素性が正確には知られていない型です。 上記の例で、我々は、クラス Buffer の各オブジェクトが 型メンバー T を持つことだけを知っています。しかしクラス Buffer の定義は、メンバー型 T がどのような具象(具体的な)型に対応するのかを明らかにしません。 値定義と同じように、サブクラス中で型定義をオーバライドできます。 これにより、(抽象型の、可能な具象インスタンス化を記述する)型境界を厳しくすることで、抽象型についてより多くの情報を明らかにできます 次のプログラムでは、型 T が新しい抽象型 U のサブ型でなければならないと述べることで、バッファ中にシーケンスのみを記憶できるクラス SeqBuffer を得ます abstract class SeqBuffer extends Buffer { type U type T Seq[U] def length = element.length } 抽象型メンバーをもつトレイトあるいはクラス [2]は、無名クラスのインスタンス化と組合せてしばしば使われます。 このことを示す例として、整数リストを参照するシーケンスバッファを扱う、次のプログラムを見てみます。 abstract class IntSeqBuffer extends SeqBuffer { type U = Int } object AbstractTypeTest1 extends Application { def newIntSeqBuf(elem1 Int, elem2 Int) IntSeqBuffer = new IntSeqBuffer { type T = List[U] val element = List(elem1, elem2) } val buf = newIntSeqBuf(7, 8) println("length = " + buf.length) println("content = " + buf.element) } メソッド newIntSeqBuf の戻り値型は、型 U が toInt に等価になった、トレイト Buffer の特化を参照します。 メソッド newIntSeqBuf 本体内における無名クラスのインスタンス化で、似たような型エイリアスを使っています。 ここで、型 T が List[Int]を参照する IntSeqBuffer の新しいインスタンスを生成します。 抽象型メンバーをクラスの型パラメータに変えることや、その逆も可能であることに注意してください。 次は、上記コードの型パラメータだけを使うバージョンです abstract class Buffer[+T] { val element T } abstract class SeqBuffer[U, +T Seq[U]] extends Buffer[T] { def length = element.length } object AbstractTypeTest2 extends Application { def newIntSeqBuf(e1 Int, e2 Int) SeqBuffer[Int, Seq[Int]] = new SeqBuffer[Int, List[Int]] { val element = List(e1, e2) } val buf = newIntSeqBuf(7, 8) println("length = " + buf.length) println("content = " + buf.element) } ここでは変位指定アノテーション [17]を使う必要があることに注意してください; そうでなければ、メソッド newIntSeqBuf が返すオブジェクトの具象シーケンス実装型を隠せなくなります。 さらにまた、型パラメータを抽象型で置き換えできない場合があります。 Scala ひと巡り アノテーション (Annotations) 原ページ アノテーションは、定義にメタ情報を関連づけます。 単純なアノテーション節は、@C あるいは @C(a1,...,an) の形です。 ここで、C はクラス C のコンストラクタで、scala.Annotation [31]に適合しなくてはなりません。 All given constructor_arguments a1,...,an must be constant_expressions (i.e., expressions on numeral literals, strings, class_literals, Java enumerations and one-dimensional arrays of them) . 与えられたコンストラクタ引数 a1,...,an はすべて、定数式(すなわち、数値リテラル、文字列、クラスリテラル、Java enumとそれらの 1 次元配列上の式)でなければなりません。 アノテーション節は、その後に続く、最初の定義または宣言に適用されます。 1 つ以上のアノテーション節が定義や宣言に先行するかもしれません。 それら節の与えられた順番は重要ではありません。 アノテーション節の意味は処理系依存です。 Java プラットフォームでは、次の Scala アノテーションは標準的な意味を持っています。 Scala Java scala.SerialVersionUID [32] serialVersionUID [33] (フィールド) scala.cloneable [34] java.lang.Cloneable [35] scala.deprecated [36] java.lang.Deprecated [37] scala.inline [38] (2.6.0から) 等価なもの無し scala.native [39] (2.6.0から) native [40] (キーワード) scala.remote [41] java.rmi.Remote [42] scala.serializable [43] java.io.Serializable [44] scala.throws [45] throws [40] (キーワード) scala.transient [46] transient [40] (キーワード) scala.unchecked [47] (2.4.0から) 等価なもの無し scala.volatile [48] volatile [40] (キーワード) scala.reflect.BeanProperty [49] Design pattern [50] 次の例では、Java main プログラム中で例外送出をキャッチするために、メソッド read の定義に throws アノテーションを加えています。 Java コンパイラは、どのチェック例外がメソッドあるいはコンストラクタの実行によって引き起こされるか分析し、プログラムがチェック例外 [51]用のハンドラを含むことを確認します。 起きる可能性のある各チェック例外に対して、メソッドあるいはコンストラクタの throw 節では、その例外クラスあるいはその例外クラスのスーパークラスの 1 つに言及しなくてはなりません。 Scala にはチェック例外がないので、Java コードが Scala メソッドの送出する例外を捕えることができるように、Scala メソッドに 1 つ以上の throws アノテーションをつける必要があります。 package examples import java.io._ class Reader(fname String) { private val in = new BufferedReader(new FileReader(fname)) @throws [45](classOf [52][IOException]) def read() = in.read() } 次の Java プログラムはファイルの内容を印字します。ファイル名は main メソッドに最初の引数として渡されます。 package [[test]]; import examples.Reader; // Scala クラス !! public class AnnotaTest { public static void main(String[] args) { try { Reader in = new Reader(args[0]); int c; while ((c = in.read()) != -1) { System.out.print((char) c); } } catch (java.io.Exception e) { System.out.println(e.getMessage()); } } } クラス Reader 中の throws アノテーションをコメントアウトすると、Java main プログラムのコンパイル時に、次のエラーメッセージが出力されます Main.java 11 Exception java.io.IOException is never thrown in body of corresponding try statement corresponding try statement } catch (java.io.IOException e) { ^ 1 error Java アノテーション 注意 Java アノテーションの -target jvm-1.5 オプションの使用を確認してください。 Java 1.5 は、アノテーション [53]の形でユーザー定義メタデータを導入しました。 アノテーションの重要な特徴は、指定された名前と値の対に依存して、それら要素を初期化することです。 例えば、もしあるクラスのソースを追跡するアノテーションが必要なら、次のように定義するかもしれません。 Java annotations @interface Source { public String URL(); public String mail(); } それを次のように適用してください @Source(URL = "http //coders.com/", mail = "support@coders.com") public class MyClass extends HisClass ... Scala のアノテーション適用は、Java アノテーションのインスタンス化のために名前付き引数を使う必要があるので、コンストラクタ呼び出しのように見えます。 @Source(URL = "http //coders.com/", mail = "support@coders.com") class MyScalaClass ... もしアノテーションが(デフォルト値をもたない) ただ 1 つの要素を含むだけなら、この構文はたいへんうんざりします。そこで、規約により(by convention)、もし名前を値として指定するなら、それをコンストラクタに似た構文を使って Java 中で適用できます。 @interface SourceURL { public String value(); public String mail() default ""; } それを次のように適用してください @SourceURL("http //coders.com/") public class MyClass extends HisClass ... In this case, Scala provides the same possiblity. この場合、Scala は同じことを提供します。 @SourceURL("http //coders.com/") class MyScalaClass ... mail 要素はデフォルト値を指定されたので、それに明示的に値を与える必要はありません。 しかし、もしそうする必要があっても、Java 中で 2 つのスタイルを混ぜて適応させることはできません。 @SourceURL(value = "http //coders.com/", mail = "support@coders.com") public class MyClass extends HisClass ... Scala はこの点に関してより柔軟です。 @SourceURL("http //coders.com/", mail = "support@coders.com") class MyScalaClass ... この拡張された構文は、.NET のアノテーションでも同じあり、それらアノテーションのフルの能力を引き出します。 Scala ひと巡り クラス (Classes) 原ページ Scala のクラスは静的なテンプレートであり、実行時にたくさんのオブジェクトへインスタンス化されます。 次は、クラス Point を定義するクラス定義です class Point(xc Int, yc Int) { var x Int = xc var y Int = yc def move(dx Int, dy Int) { x = x + dx y = y + dy } override def toString() String = "(" + x + ", " + y + ")"; } クラスは 2 つの変数 x と y、2 つのメソッド move と toString を定義します。 move は 2 つの整数を引数にとりますが、値を返しません (暗黙の戻り値型 Unit は、Java ライクな言語の void に相当します)。他方、toString は引数をとらず、String 値を返します。 toString は事前定義された toString メソッドをオーバライドするので、override フラグでタグ付けしなければなりません。 Scala のクラスは、コンストラクタ引数でパラメータ化されます。 上記のコードは 2 つのコンストラクタ引数 xc と yc を定義します;それらは共にクラス本体全体で可視です。 この例では、それらは変数 x と y の初期化に使われます。 クラスは、次の例が示すように、new プリミティブでインスタンス化されます object Classes { def main(args Array[String]) { val pt = new Point(1, 2) println(pt) pt.move(10, 10) println(pt) } } このプログラムは実行可能なアプリケーション Classes を、main メソッドをもつトップレベルのシングルトンオブジェクトの形で定義します。 main メソッドは新しい Point を生成し、それを値 pt に記憶します。 val 構文で定義された値は、それらの更新が許されない点が、var 構文(上記 クラス Point 参照)で定義された変数とは異なることに注意してください; すなわち、値(value)は不変です。 次はプログラムの出力です (1, 2) (11, 12) Scala ひと巡り ケースクラス (Case Classes) 原ページ Scala はケースクラスの概念をサポートします。ケースクラスは通常のクラスであり、そのコンストラクタ・パラメータをエクスポートし、パターンマッチィング [11]を通して再帰的な分解メカニズムを提供します。 次は、1 つの抽象スーパークラス Term と 3 つの具象ケースクラス Var、Fun と App からなるクラス階層の例です。 abstract class Term case class Var(name String) extends Term case class Fun(arg String, body Term) extends Term case class App(f Term, v Term) extends Term このクラス階層は、型付けされていない(untyped) λ計算 [54]の項を表現するのに使えます。 ケースクラスのインスタンス構築にあたり、Scala では new プリミティブを使う必要がありません。 単純に、クラス名を関数として使用できます。 次は 1 つの例です Fun("x", Fun("y", App(Var("x"), Var("y")))) ケースクラスのコンストラクタ・パラメータは公開の値として扱われ、直接アクセスできます。 val x = Var("x") Console.println(x.name) すべてのケースクラスに対して、Scala コンパイラは、構造的等価性を実装する equals メソッドと toString メソッドを生成します。 たとえば val x1 = Var("x") val x2 = Var("x") val y1 = Var("y") println("" + x1 + " == " + x2 + " = " + (x1 == x2)) println("" + x1 + " == " + y1 + " = " + (x1 == y1)) は、次のように印字するでしょう。 Var(x) == Var(x) = true Var(x) == Var(y) = false もしパターンマッチィングをデータ構造の分解に使うなら、ケースクラスを定義することは道理にかなっています。 次のオブジェクトは、λ計算を表現するプリティプリンタ関数を定義します object TermTest extends Application { def printTerm(term Term) { term match { case Var(n) = print(n) case Fun(x, b) = print("^" + x + ".") printTerm(b) case App(f, v) = Console.print("(") printTerm(f) print(" ") printTerm(v) print(")") } } def isIdentityFun(term Term) Boolean = term match { case Fun(x, Var(y)) if x == y = true case _ = false } val id = Fun("x", Var("x")) val t = Fun("x", Fun("y", App(Var("x"), Var("y")))) printTerm(t) println println(isIdentityFun(id)) println(isIdentityFun(t)) } この例で関数 print は、パターンマッチィング文として表現されており、それは match キーワードで始まる case Pattern = Body 節の並びから成っています。 上記のプログラムは、与えられた項が単純な識別関数に対応するかどうかチェックする関数 isIdentityFun も定義します。 この例は、深いパターンとガードを使います。 与えられた値をもつパターンとマッチした後、その(キーワード if の後に定義された)ガードが評価されます。 もしそれが true を返すなら、マッチは成功です。;そうでなければ失敗であり、次のパターンが試みられます。 Scala ひと巡り 事前定義された classOf 関数 (Predefined function classOf) 原ページ 事前定義された関数 classOf[T]は、 Scala のクラス型 T の実行時表現を返します。 次の Scala コード例は、 args パラメータの実行時表現を印字します object ClassReprTest { abstract class Bar { type T AnyRef def bar(x T) { println("5 " + x.getClass()) } } def main(args Array[String]) { println("1 " + args.getClass()) println("2 " + classOf[Array[String]]) new Bar { type T = Array[String] val x T = args println("3 " + x.getClass()) println("4 " + classOf[T]) }.bar(args) } } 次は Scala プログラムの出力です 1 class [Ljava.lang.String; 2 class [Ljava.lang.String; 3 class [Ljava.lang.String; 4 class [Ljava.lang.String; 5 class [Ljava.lang.String; Scala ひと巡り 複合型 (Compound Types) 原ページ ときには、オブジェクトの型が、他の複数の型のサブ型であると表現することが必要になります。 Scala では、それをオブジェクト型の論理積である複合型(compound types)の助けをかりて表現できます。 2 つのトレイト Cloneable と Resetable があるとします。 trait Cloneable extends java.lang.Cloneable { override def clone() Cloneable = { super.clone(); this } } trait Resetable { def reset Unit } いま、オブジェクトを引数にとってクローンし、オリジナルのオブジェクトをリセットする関数 cloneAndReset を書きたいとします。 def cloneAndReset(obj ?) Cloneable = { val cloned = obj.clone() obj.reset cloned } パラメータ obj の型は何か、という問題が生じます。 もしそれが Cloneable なら、オブジェクトはクローンできますがリセットできません。; しかしもし Resetable なら、リセットできますがクローン操作がありません。 そのような状況で型キャストを避けるために、obj の型が Cloneable と Resetable の両方であると指定できます。 Scala では、複合型を使って Cloneable with Resetable のように書きます。 次は、アップデートした関数です def cloneAndReset(obj Cloneable with Resetable) Cloneable = { //... } 複合型は複数のオブジェクト型からなり、既存のオブジェクトメンバーのシグニチャを狭めるのに使える、ただ一つの細別(refinement)を持てます。 一般的な書き方は A with B with C ... { refinement } です。 細別の使用例は、抽象型 [21]に関するページにあります。 Scala ひと巡り シーケンス内包表記 (Sequence Comprehensions) 原ページ Scala は、シーケンス内包表記式に対して簡単な表記法を提供します。 内包表記は for enums yield e の形をしています。ここで enums は、セミコロンで分離された列挙子のリストを参照します。 列挙子は、新しい変数を導入する生成子、あるいは、フィルタです。 内包表記は、列挙子 enum によって生成された各束縛にごとに、本体 e を評価し、それら値のシーケンスを返します。 次は 1 つの例です object ComprehensionTest1 extends Application { def even(from Int, to Int) List[Int] = for (i - List.range(from, to) if i % 2 == 0) yield i Console.println(even(0, 20)) } 関数 even 中の for 式は Int 型の新しい変数 i を導入し、それをリスト List(from,from + 1,...,to - 1) の全ての値へ次々に束縛します。 ガード if i % 2 == 0 は、(式 i だけからなる)本体が偶数の場合のみ評価されるよう、全ての奇数をフィルターします。 最終的に、for 式全体は偶数のリストを返します。 プログラムは次を出力します List(0, 2, 4, 6, 8, 10, 12, 14, 16, 18) 次はより複雑な例で、その合計が与えられた値 v と等しい、0 から n - 1 までの数の対をすべて計算します。 object ComprehensionTest2 extends Application { def foo(n Int, v Int) = for (i - 0 until n; j - i + 1 until n if i + j == v) yield Pair(i, j); foo(20, 32) foreach { case (i, j) = println("(" + i + ", " + j + ")") } } この例は、内包表記がリストに制限されないことを示しています。 前のプログラムは、代わりにイテレータを使っています。 (適切な型をもつ) 操作 filter、map そして flagMapをサポートするすべてのデータ型は、シーケンス内包表記中で使えます。 次はプログラムの出力です (13, 19) (14, 18) (15, 17) シーケンス内包表記で Unitを返す、特別の形式もあります。 そこでは、生成子のリストとフィルターから生成される束縛は、副作用を起こさせるために使われます。 そのようなシーケンス内包表記を利用するには、プログラマはキーワード yield を取り除かなければなりません。 次は、前のものと等価ではあるが Unit を返す、特別な for 内包表記を使うプログラムです。 object ComprehensionTest3 extends Application { for (i - Iterator.range(0, 20); j - Iterator.range(i + 1, 20) if i + j == 32) println("(" + i + ", " + j + ")") } Scala ひと巡り 抽出子オブジェクト (Extractor Objects) 原ページ Scala では、パターンをケースクラスとは独立に定義できます。 この目的のために、unapply という名前のメソッドが定義されて、いわゆる抽出子をもたらします。 例えば、次のコードは抽出子オブジェクト Twice を定義します。 object Twice { def apply(x Int) Int = x * 2 def unapply(z Int) Option[Int] = if (z%2 == 0) Some(z/2) else None } object TwiceTest extends Application { val x = Twice(21) x match { case Twice(n) = Console.println(n) } // prints 21 } 次は、ここで関係する 2 つの文法上の規約(convention)です パターン case Twice(n)は、Twice.unapply の呼び出しを引き起こし、偶数のマッチに使われます。; unapply の戻り値は、引数がマッチしたかどうか、そしてさらなるマッチングのために使えるサブ値を伝えます。 ここで、サブ値は z/2 です。 The apply_method is not necessary for pattern matching. It is only used to mimic a constructor val x = Twice(21) expands to val x = Twice.apply(21) . apply メソッドは、パターンマッチィングについては必須ではありません。 これはただ、コンストラクタをまねて val x = Twice(21) を val x = Twice.apply(21) へ展開する時に使われるだけです。 unapply の戻り値型は、次のように選ぶべきです もしそれが単なるテストなら、Boolean を返す。たとえば case even() 。 もしそれがただ一つの、型 T のサブ値を返すなら、Option[T]を返す。 もし複数のサブ値 T1,...,Tn を返したいなら、 それらをまとめてタプルのオプション Option[(T1,...,Tn)]として返す。 しばしば、サブ値の数が固定で、シーケンスを返したいことがあります。 その場合は、unapplySeq を介して同様にパターンを定義できます。 最後のサブ値の型 Tn は、Seq[S]でなければなりません。 このメカニズムは、たとえば、パターン case List(x1,...,xn) 中で使われます。 抽出子を使えば、コードはさらに保守しやすくなります。 詳細は、Emir [56]、Odersky[57] と Williams (2007 年 1 月) らによる論文「 パターンを用いたオブジェクトマッチング」[55](4 章参照) を読んでください。 目次 次
https://w.atwiki.jp/wayofcaliforniawine/pages/25.html
ワイナリー訪問その17 San Benito Calera(カレラ) Calera Wine Company(2011年12月訪問) 日本で大人気のCalera。南カリフォルニアからサンフランシスコへと移動する道すがら、ちょっと寄り道して訪問した。この頃は決してピノ好きというわけではない私だったが、Caleraと聞けばさすがにテンションが上がった。 自分などが書くまでもないこととは思うが、オーナーのジョシュ・ジェンセン氏はフランスのD.R.C.(ドメーヌ・ド・ラ・ロマネ・コンティ)で働きながらワイン造りの勉強をしたのだそうで、日本ではここのピノは「カリフォルニアのロマネ・コンティ」等と持てはやされているようだ。ここのフラッグシップワインたるCalera PINOT NOIR Jensenは、米国で60ドル程度なのに対し、日本では1万円を割ることは稀っぽい。 石灰質の土壌を求めてカリフォルニア中を2年間調べ尽くした末に購入したという土地は、ナパとは違ってワイナリーが林立するような場所ではなく、かなりへんぴな場所にある。山道をくねくね進んだ末に、カレラの小さな看板を発見したときは、中々感慨深いものがあった。ただ、後から聞いた話によると、噂の葡萄畑は、我々が訪れたテイスティングルームよりももっと南に5マイルくらいいった所にあるのだとか…有名な石灰石のタワーもそこにあるのだそうで、今回見られず残念。 テイスティングルームは、倉庫の一部を使っているような感じ。訪れたのは日曜の昼ごろだったが、客は我々だけだった。人の良さそうなおっちゃん(むしろおじいちゃんという感じの方)が、1人で対応していた。 テイスティング料は、記憶がおぼろげだが確か15ドル。10種類飲ませてくれた。 Aligote 2010 ($20) Chardonnay CENTRAL COAST 2010 ($18) Chardonnay MT. HARLAN 2010 ($30) Viognier CENTRAL COAST 2010 ($16) Pinot Noir CENTRAL COAST 2010 Pinot Noir CENTRAL COAST 2009 ($24) Pinot Noir Mills 2008 ($45) Pinot Noir de Villiers 2009 ($35) Pinot Noir Ryan 2008 ($40) Pinot Noir Ryan 2006 Viognier Doux 2010 最後に飲ませてもらったデザートワインが大変美味しかった。爽やかな香りが強く、上品な甘酸っぱさで。 ピノの中では、de Villiers 2009が、華やかな香りが強く感じられ、その割に値段が安いので、一番コストパフォーマンスが良いように思われた。 ただ、以前どこかのブログで読んだ話によると、日本のイベントに参加したジョシュ・ジェンセン氏が、ここのピノのジェンセンとかセレックとかは、何年も寝かせて初めて本領を発揮すると語っていたらしいので、数年後に飲むと他のものの方がうまいと感じるのかも知れない。 おみやげに何かボトルを買おうと思い、何にしようか色々考えていると、 「2000年のMillsがあるよ」とか、 「2007年のJensenもあるよ」とか、 おっちゃんが控えめに色々と教えてくれた。結局、試飲したデザートワインと、2007年のJensenを購入することにした。 2007年のJensenは、ロバート・パーカー氏に97点と高く評価されてしまったせいもあってか、小売店でお目にかかったことがない。ここぞという時に飲むことにしようと思った。 それはそうと、試飲中に、ふらりとジョシュ・ジェンセン氏が登場。Webで見たのと同じ顔だった。噂通り背が高い。私にしては珍しく、一緒に写真を撮ってもらおうと思い、お願いしてみた。ジェンセン氏は快く承諾してくれたのだが、ワイナリーの人が撮影してくれたその写真は、ピントが合わずボケまくり。「もう1回、半押ししてから、さらに押し込んで撮影してね」とか指示するのも何となく憚られたし、まあ、あきらめることにしておいた。たぶん、慣れないことはするなという神のお告げだろう。 1つ前のワイナリー訪問へ 次のワイナリー訪問へ 関連項目 家飲みワイン Calera PINOT NOIR Jensen 2006 Calera PINOT NOIR Jensen 2007 Calera PINOT NOIR de Villiers 2012 Calera PINOT NOIR de Villiers 2014 Calera VIOGNIER DOUX 2010 ワイナリーのWebサイトはこちら:http //www.calerawine.com/
https://w.atwiki.jp/tmiya/pages/128.html
Scala ひと巡り sealed クラス (Sealed Classes) 原ページ sealed クラスは、継承するテンプレートを継承されるクラスと同じソースファイル中で定義する場合を除き、直接には継承できません。しかし、sealed クラスのサブクラスはどこででも継承できます。 sealed クラスは sealed 修飾子を使って定義できます。 もしパターンマッチのセレクタが sealed クラスのインスタンスなら、パターンマッチングのコンパイル時に、与えられたパターンセットが網羅的ではないと診断する警告が出ます。すなわち、実行時に MatchError [60] が発生する可能性があるということです。 @unchecked アノテーション [47] をマッチ式のセレクタに適用すると、そうでなければ発せられるはずの、非網羅的パターンマッチに関するあらゆる警告が抑制されます。 例えば、次のメソッド定義に対しては警告はありません。 def f(x Option[Int]) = (x @unchecked) match { case Some(y) = y } @unchecked アノテーションがなければ、Scala コンパイラはパターンマッチが非網羅的であると推論し、Optionが sealed クラスなので警告を発します。 Scala ひと巡り トレイト (Traits) 原ページ トレイトは、Java のインターフェースに似て、サポートするメソッドのシグニチャを記述することで、オブジェクトの型定義に使えます。Java と異なり、Scala のトレイトは部分的に実装できます。すなわち、複数のメソッドのデフォルト実装を定義できます。クラス [2]と異なり、トレイトはコンストラクタ・パラメータを持てません。 次は 1 つの例です trait Similarity { def isSimilar(x Any) Boolean def isNotSimilar(x Any) Boolean = !isSimilar(x) } このトレイトは 2 つのメソッド isSimilar と isNotSimilar からなります。isSimilar が具象の(具体的な)メソッド実装を提供せず(Java 用語では抽象)、メソッド isNotSimilar は具象実装を定義します。従って、このトレイトを統合するクラスだけが、isSimilar に具象の実装を提供する必要があります。isNotSimilar の振る舞いは、トレイトから直接に継承します。トレイトは通常、ミックスインクラス合成 [5]を用いて、クラス [61](あるいは他のトレイト)に統合されます class Point(xc Int, yc Int) extends Similarity { var x Int = xc var y Int = yc def isSimilar(obj Any) = obj.isInstanceOf[Point] obj.asInstanceOf[Point].x == x } object TraitsTest extends Application { val p1 = new Point(2, 3) val p2 = new Point(2, 4) val p3 = new Point(3, 3) println(p1.isNotSimilar(p2)) println(p1.isNotSimilar(p3)) println(p1.isNotSimilar(2)) } 次はプログラムの出力です false true true Scala ひと巡り 上限 型境界 (Upper Type Bounds) 原ページ Scala では、型パラメータ [16]と抽象型 [21]は、型境界による制約を受けます。そのような型境界は、型変数の具象値を制限し、型のメンバーについてさらに多くの情報を明らかにします。上限型境界 T A は、型変数 T が型 A のサブ型を参照することを宣言します。 次は、多相的メソッド [25] findSimilar の実装について、上限型境界に頼る例です trait Similar { def isSimilar(x Any) Boolean } case class MyInt(x Int) extends Similar { def isSimilar(m Any) Boolean = m.isInstanceOf[MyInt] m.asInstanceOf[MyInt].x == x } object UpperBoundTest extends Application { def findSimilar[T Similar](e T, xs List[T]) Boolean = if (xs.isEmpty) false else if (e.isSimilar(xs.head)) true else findSimilar[T](e, xs.tail) val list List[MyInt] = List(MyInt(1), MyInt(2), MyInt(3)) println(findSimilar[MyInt](MyInt(4), list)) println(findSimilar[MyInt](MyInt(2), list)) } 上限型境界アノテーションがなければ、メソッド findSimilar 中でメソッド isSimilar を呼び出すことはできません。 下限型境界の使用方法は、次で述べます [19]。 Scala ひと巡り 下限 型境界 (Lower Type Bounds) 原ページ 上限型境界 [18]は、型を他の型のサブ型へ制限し、他方、下限型境界は、型が他の型のスーパー型であると宣言します。項 T A は、型パラメータ T あるいは抽象型 T が、型 A のスーパー型を参照することを表します。 次はそれが役に立つ例です case class ListNode[T](h T, t ListNode[T]) { def head T = h def tail ListNode[T] = t def prepend(elem T) ListNode[T] = ListNode(elem, this) } 上記のプログラムは prepend (先頭に追加)操作を使って連結リストを実装します。残念ながら、この型は、クラス ListNode の型パラメータ中にあって、非変です; すなわち、型 ListNode[String]は 型 List[Object]のサブ型ではありません。変位指定アノテーション [17]の助けを借りて、このようなサブ型のセマンティクスを表現できます case class ListNode[+T](h T, t ListNode[T]) { ... } 残念ながら、共変の変位指定は型変数を共変の位置で使う場合のみ可能なので、このプログラムはコンパイルできません。型変数 T はメソッド prepend のパラメータ型として現われるので、この規則は破られています。しかし、下限型境界の助けを借りれば、T が共変の位置のみに現れる prepend メソッドを実装できます。 次は対応するコードです case class ListNode[+T](h T, t ListNode[T]) { def head T = h def tail ListNode[T] = t def prepend[U T](elem U) ListNode[U] = ListNode(elem, this) } 新しい prepend メソッドは、少しばかり制約の少ない型を持つことに注意してください。これにより、たとえば、既に存在するリストの先頭にスーパー型のオブジェクトを追加できます。得られるリストは、このスーパー型のリストです。 次は、そのことを示すコードです object LowerBoundTest extends Application { val empty ListNode[Null] = ListNode(null, null) val strList ListNode[String] = empty.prepend("hello") .prepend("world") val anyList ListNode[Any] = strList.prepend(12345) } Scala ひと巡り 明示的に型付けられた自己参照 (Explicitly Typed Self References) 原ページ 拡張可能なソフトウェアを開発するとき、値 this の型を宣言したくなることが時々あります。興味を引く例として、グラフデータ構造の小規模で拡張可能な表現を Scala で考えてみましょう。 次はグラフを記述する定義です abstract class Graph { type Edge type Node NodeIntf abstract class NodeIntf { def connectWith(node Node) Edge } def nodes List[Node] def edges List[Edge] def addNode Node } グラフはノードとエッジのリストからなり、それらノードとエッジの両方の型とも抽象のままです。 The use of abstract types [21] allows implementations of trait Graph to provide their own concrete classes for nodes and edges. 抽象型 [21]を使えば、ノードとエッジに対してそれら自身の具象クラスを提供できるようにする、トレイト Graph を実装できます。 さらに、グラフに新しいノードを加える、メソッド addNode があります。ノードはメソッド connectWith を使って連結します。 次のプログラムは、クラス Graph の 1 つの考え得る実装です。 abstract class DirectedGraph extends Graph { type Edge EdgeImpl class EdgeImpl(origin Node, dest Node) { def from = origin def to = dest } class NodeImpl extends NodeIntf { def connectWith(node Node) Edge = { val edge = newEdge(this, node) edges = edge edges edge } } protected def newNode Node protected def newEdge(from Node, to Node) Edge var nodes List[Node] = Nil var edges List[Edge] = Nil def addNode Node = { val node = newNode nodes = node nodes node } } クラス DirectedGraph は、部分的な実装を提供することで、Graph クラスを特化します。実装は本当に部分的です。なぜなら DirectedGraph をさらに拡張できるようにしたいからです。そのために、このクラスではすべての実装詳細をオープンにし、このようにノードとエッジの両方とも抽象のままにしています。にもかかわらず、クラス DirectedGraph は、クラス EdgeImpl へ境界を厳しくすることで、エッジ型の実装についてさらなる詳細を明示しています。また、クラス EdgeImpl と NodeImpl で表される、エッジとノードの準備的な実装がいくつかあります。部分的なグラフ実装の中で新しいノードとエッジオブジェクトを生成する必要があるので、ファクトリメソッド newNode と newEdge も加えなければなりません。メソッド addNode と connectWith は共に、これらのファクトリメソッドを使って定義します。メソッド connectWith の実装をよく見ると、エッジを生成するために、自己参照 this をファクトリメソッド newEdge に渡す必要があることがわかります。しかし this は型 NodeImpl に割り当てられており、それは対応するファクトリメソッドによって要請される型 Node に互換ではありません。その結果、上記のプログラムは正しくなく、Scala コンパイラはエラーメッセージを発行します。 Scala では、自己参照 this に他の型を明示的に与えることで、クラスを(将来実装されるであろう)もう 1 つの型に結び付けることができます。このメカニズムを使って上記コードを修正できます。明示的な自己型は、クラス DirectedGraph の本体中で指定します。 次は修正したプログラムです abstract class DirectedGraph extends Graph { ... class NodeImpl extends NodeIntf { self Node = def connectWith(node Node) Edge = { val edge = newEdge(this, node) // 今度は OK edges = edge edges edge } } ... } クラス NodeImpl の新しい定義では、this は型 Node を持っています。型 Node は抽象ですから、NodeImpl が本当に Node のサブ型かどうかはまだわからず、Scala の型システムは、このクラスのインスタンス化を許してくれません。 But nevertheless, we state with the explicit type_annotation of this that at some point, (a subclass of) NodeImpl has to denote a subtype of type Node in order to be instantiatable . しかしそれにもかかわらず、インスタンス化できるようにするために、ある時点で NodeImpl (のサブクラスの 1 つ)が型 Node のサブ型を表さなければならないことを、this の明示的なアノテーション型を用いて記述します。 次は、DirectedGraph の具象特化であり、すべての抽象クラスメンバが具象に変わっています。 class ConcreteDirectedGraph extends DirectedGraph { type Edge = EdgeImpl type Node = NodeImpl protected def newNode Node = new NodeImpl protected def newEdge(f Node, t Node) Edge = new EdgeImpl(f, t) } この場合、NodeImpl をインスタンス化できます。なぜなら、今度は NodeImpl が(単純に NodeImpl のエイリアスである)型 Node のサブ型を表すことがわかるからです。 次は、クラス ConcreteDirectedGraph の使用方法を示す例です object GraphTest extends Application { val g Graph = new ConcreteDirectedGraph val n1 = g.addNode val n2 = g.addNode val n3 = g.addNode n1.connectWith(n2) n2.connectWith(n3) n1.connectWith(n3) } Scala ひと巡り サブクラス化 (Subclassing) 原ページ Scala のクラスは拡張可能です。サブクラスの機構により、与えられたスーパークラスの全メンバーの継承と、クラスメンバの追加定義によって、クラスを特化できます。 次は 1 つの例です class Point(xc Int, yc Int) { val x Int = xc val y Int = yc def move(dx Int, dy Int) Point = new Point(x + dx, y + dy) } class ColorPoint(u Int, v Int, c String) extends Point(u, v) { val color String = c def compareWith(pt ColorPoint) Boolean = (pt.x == x) (pt.y == y) (pt.color == color) override def move(dx Int, dy Int) ColorPoint = new ColorPoint(x + dy, y + dy, color) } この例では最初に、場所を表す新しいクラス Point を定義します。次に、クラス Point を拡張するクラス ColorPoint を定義します。 これは次のような結果になります: クラス ColorPoint は、そのスーパークラス Point からすべてのメンバーを継承します。;この場合、メソッド move と同様、値 x、y も継承します。 サブクラス ColorPoint は、(継承した)メソッドの集合に新しいメソッド compareWith を加えます。 Scala ではメンバー定義をオーバライドできます; この場合、クラス Point から継承した move メソッドをオーバライドします。これにより、ColorPoint オブジェクトのクライアントは、クラス Point の move メソッドにアクセスできなくなります。クラス ColorPoint 内では、継承されたメソッド move は スーパー呼び出し super.move(...) を使ってアクセスできます。メソッドオーバーライドが非変の(つまり、オーバーライドするメソッドが同じシグニチャを持たなければならない) Java と異なり、Scala では反変/共変方式でメソッドをオーバライドできます。上の例では、このフィーチャーを利用してメソッド move に、スーパークラス Point で指定された Point オブジェクトを返す代わりに ColorPoint オブジェクトを返させています。 サブクラスはサブ型を定義します; このことは今の場合、Point オブジェクトが必要とされるときはいつでも、ColorPoint オブジェクトを使えることを意味します。 複数の他クラスを継承したい場合、純粋なサブクラス化ではなく、ミックスインベースのクラス合成 [5] を利用する必要があります。 Scala ひと巡り ローカルな型推論 (Local Type Inference) 原ページ Scala は、プログラマが明白なアノテーション型を書かなくても済む、組み込みの型推論機構を持っています。たとえば Scalaでは、変数の型を指定する必要がないことがよくあります。なぜなら、コンパイラが変数の初期化式から型を推論できるからです。同様にメソッドの戻り値型もしばしば省略できます。なぜなら、それらは本体の型に対応するので、コンパイラが推論できるからです。 次は 1 つの例です object InferenceTest1 extends Application { val x = 1 + 2 * 3 // x の型は Int val y = x.toString() // y の型は String def succ(x Int) = x + 1 // メソッド succ は Int 値を返す } 再帰的なメソッドについては、コンパイラは結果型を推論できません。次のプログラムは、この理由でコンパイルできません。 object InferenceTest2 { def fac(n Int) = if (n == 0) 1 else n * fac(n - 1) } 多相的メソッド [25]を呼ぶあるいは、ジェネリッククラス [16]をインスタンス化するとき、型パラメータの指定も必須ではありません。Scala コンパイラは、コンテキストや実際のメソッド/コンストラクタ・パラメータの型からそのような記述されていない型パラメータを推論します。 次はこのことを示す例です case class MyPair[A, B](x A, y B); object InferenceTest3 extends Application { def id[T](x T) = x val p = new MyPair(1, "scala") // 型 MyPair[Int, String] val q = id(1) // 型 Int } 上記プログラムの最後の 2 行は、推論された型をすべて明示した、次のコードに等価です val x MyPair[Int, String] = new MyPair[Int, String](1, "scala") val y Int = id[Int](1) ある状況では、次のプログラムが示すように、Scala の型推論機構に頼ることは非常に危険です。 object InferenceTest4 { var obj = null obj = new Object() } このプログラムはコンパイルできません。なぜなら、変数 obj の推論される型は Null だからです。この型の唯一の値は nullですから、この変数に他の値を参照させることはできません。 Scala ひと巡り 統合された型 (Unified Types) 原ページ Java と異なり、Scala ではすべての値はオブジェクトです(数値や関数を含めて)。Scala はクラスを基盤にしているので、すべての値はクラスのインスタンスです。下図は Scala のクラス階層を示しています。 imageプラグインエラー ご指定のURLはサポートしていません。png, jpg, gif などの画像URLを指定してください。 Scala クラス階層 全てのクラスのスーパークラスである scala.Any は直下にサブクラス scala.AnyValue と AnyRef を持っています。それらは 2 つの異なるクラスの系統 値クラスと参照クラスを代表しています。すべての値クラスは事前定義されています;それらは Java ライクな言語のプリミティブ型に対応します。他のすべてのクラスは参照型を定義します。ユーザー定義のクラスは、デフォルトでは参照型を定義します; つまり、それらはいつも(間接的に)scala.AnyRef のサブクラスとなります。Scala のユーザー定義クラスはすべて、暗黙のうちにトレイト scala.ScalaObject を拡張(継承)します。Scala 実行基盤からのクラス(つまり Java 実行時環境)は、scala.ScalaObject を拡張しません。もし Scala を Java 実行時環境のコンテキスト中で使うなら、scala.AnyRef は java.lang.Object に対応します。 上図は、値クラス間のビュー [24]と呼ばれる暗黙の型変換も示していることに注意してください。 次の例は、数、文字、論理値等と関数の双方とも、他のオブジェクトとまったく同じく、オブジェクトであることを示しています。 object UnifiedTypes { def main(args Array[String]) { val set = new scala.collection.mutable.HashSet[Any] set += "This is a string" // 文字列の追加 set += 732 // 数の追加 set += c // 文字の追加 set += true // 論理値の追加 set += main _ // main 関数の追加 val iter Iterator[Any] = set.elements while (iter.hasNext) { println(iter.next.toString()) } } } プログラムは、トップレベルのシングルトンオブジェクトの形で、main メソッドをもつアプリケーション UnifiedTypes を宣言します。main メソッドは、クラス HashSet[Any]のインスタンスを参照するローカル変数 set を定義します。プログラムはこの set に様々な要素を加えます。要素は、宣言されたセット要素型 Any に適合しなければなりません。最後に、すべての要素の文字列表現を印字します。 次はプログラムの出力です c true function 732 This is a string Scala ひと巡り 変位指定 (Variances) 原ページ Scala は、ジェネリッククラスの型パラメータ [16]の変位指定アノテーションをサポートします。Java5 (aka.JDK 1.5[58])と対照して、クラス抽象を定義するときに変位指定アノテーションを加えることができます。他方、Java5 では、変位指定アノテーションはクラス抽象を使うときにクライアントが与えます。(訳注:Scalaでは静的に表現できるということ) ジェネリッククラスについてのページに、ミュータブル(更新可能)なスタックの例がありました。クラス Stack[T] によって定義された型は、型パラメータについて非変のサブ型付けになると説明しました。それによりクラス抽象の再利用を制限できます。今度はこの制限を持たないスタックの関数型(つまり、イミュータブル(更新不可)な)実装を導きます。これが、明白ではない方法で多相的メソッド [25]、下限型境界 [19]、そして共変の型パラメータアノテーションの使用を結びつける、進んだ例であることに注意してください。さらにまた、スタック要素を明示的なリンクなしでチェインするために、内部クラス [20]を利用します。 class Stack[+A] { def push[B A](elem B) Stack[B] = new Stack[B] { override def top B = elem override def pop Stack[B] = Stack.this override def toString() = elem.toString() + " " + Stack.this.toString() } def top A = error("no element on stack") def pop Stack[A] = error("no element on stack") override def toString() = "" } object VariancesTest extends Application { var s Stack[Any] = new Stack().push("hello"); s = s.push(new Object()) s = s.push(7) Console.println(s) } アノテーション +T は、型 T が共変の位置でだけ使われると宣言します。同様に、-T は、T が反変の位置でだけ使われると宣言します。共変の型パラメータなので、この型パラメータについて共変のサブ型関係を得ます。この例では、もし T が S のサブ型なら、このことは、Stack[T] が Stack[S]のサブ型であることを意味します。 - とタグ付けられた型パラメータについては、反対のことが当てはまります。スタックの例では、メソッド push を定義できるようにするために、反変の位置で共変型パラメータ T を使う必要があります。スタックは共変のサブ型付けにしたいのですから、トリックを使います。メソッド push のパラメータ型上で抽象化します。push の型変数の下限境界として要素型 T を使う多相的メソッド [25]を得ます。これには、その共変型パラメータとしての宣言と協調する T の変位指定を持ち込む効果があります。今、スタックは共変です。しかしこのソリューションによれば、たとえば、整数スタック上に文字列をプッシュすることが可能となります。戻り値は型 Stack[Any] のスタックです。;整数スタックを期待するコンテキスト中で戻り値を使う場合にだけ、実際にエラーを検出します。そうでない場合、より汎用的な要素型のスタックを得ます。 Scala ひと巡り ビュー (Views) 原ページ 暗黙のパラメータ [63]とメソッドは、ビューと呼ばれる暗黙の型変換も定義できます。型 S から型 T へのビューは、関数型 S = T を持つ暗黙の値によって、あるいは、その型の値に変換可能なメソッドによって定義されます。 ビューは 2 つの状況で適用されます 式 e が型 T で、T が式の要請型(期待される型) pt に適合しないとき 型 T の e の選択 e.m 中で、セレクタ m が T のメンバーを意味しないとき 最初の場合は、 e に適用可能でその結果型が pt に適合するビュー v が検索されます。2 番目の場合は、e に適用可能でその結果型が m という名前のメンバーを含むビュー v が検索されます。 型 List[Int]の 2 つのリスト xs と ys 上の、次の操作は正しいです。 xs = ys ただし、下記で定義された 暗黙のメソッド list2ordered と int2ordered がスコープ中にあると仮定して implicit def list2ordered[A](x List[A]) (implicit elem2ordered a = Ordered[A]) Ordered[List[A]] = new Ordered[List[A]] { /* .. */ } implicit def int2ordered(x Int) Ordered[Int] = new Ordered[Int] { /* .. */ } list2ordered 関数は、型パラメータの可視境界(view bound:ビュー境界)を使っても表現できます implicit def list2ordered[A % Ordered[A]](x List[A]) Ordered[List[A]] = ... Scala コンパイラはこのとき、上記で与えられた list2ordered の定義に等価なコードを生成します。 暗黙のうちにインポートされる [64] オブジェクト scala.Predef は、いくつかの事前定義された型(たとえば Pair)とメソッド(たとえば error)ばかりでなく、いくつかのビューも宣言します。次の例は、事前定義されたビュー charWrapper のアイデアを示します final class RichChar(c Char) { def isDigit Boolean = Character.isDigit(c) // isLetter, isWhitespace, etc. } object RichCharTest { implicit def charWrapper(c char) = new RichChar(c) def main(args Array[String]) { println( 0 .isDigit) } } Scala ひと巡り XML 処理 (XML Processing) 原ページ Scala を使えば、XML ドキュメントの生成、解析、処理が簡単に行えます。Scala では、XML データをジェネリックなデータ表現を使うことであるいは、データに特化したデータ表現を用いて表現できます。後者の方法は、データ結合ツール schema2src によってサポートされます。 実行時表現 XML データはラベル付きのツリーとして表現されます。Scala 1.2から始まり(以前のバージョンでは -Xmarkup オプションを使う必要があります)、そのようなラベル付きノードを標準的な XML 構文を使って簡単に生成できます。 次の XML ドキュメントについて考えます。 html head title Hello XHTML world /title /head body h1 Hello world /h1 p a href="http //scala-lang.org/" Scala /a talks XHTML /p /body /html このドキュメントは、次の Scala プログラムで生成できます。 object XMLTest1 extends Application { val page = html head title Hello XHTML world /title /head body h1 Hello world /h1 p a href="scala-lang.org" Scala /a talks XHTML /p /body /html ; println(page.toString()) } Scala 式と XML をミックスできます。 object XMLTest2 extends Application { import scala.xml._ val df = java.text.DateFormat.getDateInstance() val dateString = df.format(new java.util.Date()) def theDate(name String) = dateMsg addressedTo={ name } Hello, { name }! Today is { dateString } /dateMsg ; println(theDate("John Doe").toString()) } データの結合 多くの場合、人は処理したい XML ドキュメントに関する DTD を持っています。そのための特別な Scala クラスを生成し、XML を解析し保存するためのコードがほしいことでしょう。Scala は、DTD を Scalaクラス定義 のコレクションに変えるといったことをあなたに代わって全部やってくれる、気のきいたツールになります。 schema2src ツールを使った文書化と例は、Burak のドラフト Scala xml book [65] にあることを書き留めておきます。 前 はじめ
https://w.atwiki.jp/tmiya/pages/129.html
Scala ひと巡り (A Tour of Scala) 原ページ Published on The Scala Programming Language (http //www.scala-lang.org) . By admin . Created 2008-07-05, 20 31 ●学習者の参考になればと思って訳してみましたが、誤訳の可能性大ですので、正しいことを知りたい方は必ず原文をお読みください。ご意見その他は、このページの下へ投稿してください。 Scala は簡潔でエレガント、そして型安全な方法で共通のプログラミングパターンを表現できるよう設計された現代的なマルチパラダイム・プログラミング言語です。オブジェクト指向と関数型言語の特質をスムーズに統合します。 Scala はオブジェクト指向言語です すべての値がオブジェクトである [1]という意味で、Scala は純粋なオブジェクト指向言語です。オブジェクトの型と振る舞いをクラス [2]とトレイト [3]によって記述します。クラスはサブクラス化 [4]と、多重継承の欠点のない置換えである、柔軟なミックスインベースの合成 [5]メカニズムにより拡張されます。 Scala は関数型言語です すべての関数が値である[1]という意味で、Scala は関数型言語でもあります。Scala は無名関数の定義に簡単な構文 [6]を提供します。それは高階関数 [7]をサポートし、関数のネストを可能とし[8]、カリー化 [9]をサポートします。Scala のケースクラス [10]とパターンマッチング [11]の組み込みサポートは、多くの関数型プログラミング言語で使われる代数型をモデル化します。 さらに、Scala のパターンマッチングの概念は、右無視シーケンスパターン(right-ignoring sequence pattern) [13]の助けにより、XML データ [12]の処理へ自然に拡張されます。このコンテキストにおいて、シーケンス内包表記(sequence comprehensions) [14]はクエリの設計に役立ちます。 これらの特徴により Scala は、Web サービス[15]のようなアプリケーション開発に理想的なものとなっています。 Scala は静的な型付け言語です Scala は、抽象化が安全で首尾一貫した方法でなされることを静的に強制する、表現力豊かな型システムを備えています。 特に、型システムは次をサポートします。 ジェネリッククラス (generic classes [16]) 変位指定アノテーション (variance annotations [17]) 上/下限 型境界 (upper[18] and lower[19] type bounds) 内部クラスとオブジェクトメンバーとしての抽象型(inner classes [20] and abstract types [21] as object members) 複合型 (compound types [22]) 明示的に型付けされた自己参照 (explicitly typed self references [23]) ビュー (view [24]) 多相的メソッド (polymorphic methods [25]) ローカルな型推論 [26]機構のおかげで、ユーザーはプログラムに冗長な型情報で注釈を付ける必要がありません。これらフィーチャーの組み合わせは、プログラミング抽象の安全な再利用とソフトウェアの型安全な拡張に、強力な基盤を提供します。 Scala は拡張性に富んでいます 現場では、固有領域のアプリケーション開発はしばしば領域固有の言語拡張を必要とします。Scala は、新たな言語要素をライブラリの形でスムーズに容易に加えることのできる、言語メカニズムのユニークな組合せを提供します どのようなメソッドも中置あるいは後置演算子 [27]として使えます。そして 要請型(expected type 期待される型)に応じて、クロージャが自動的に構成されます[28](target typing ターゲットによる型付け)。 両フィーチャーの併用により、構文拡張なしで、またマクロのようなメタプログラミング機能の助けを借りずに、新しい構文を簡単に定義できるようになります。 Scala は Java や .NET と相互運用できます Scala は、ポピュラーな Java 2 実行環境(JRE [29])とうまく相互運用できるように設計されています。特に、主流のオブジェクト指向 Java プログラミング言語との相互作用は可能な限りスムーズです。Scala は、Java と同列のコンパイルモデル(ダイナミックなクラスローディング、分割コンパイル)を採用しており、既存の多数の高品質ライブラリにアクセスできます。.NET フレームワーク(CLR [30])のサポートも利用できます。 さらに次のページをお読みください。 Scala ひと巡り 抽象型 (Abstract Types) Scala ひと巡り アノテーション (Annotations) Scala ひと巡り クラス (Classes) Scala ひと巡り ケースクラス (Case Classes) Scala ひと巡り 事前定義された classOf 関数 (Predefined function classOf) Scala ひと巡り 複合型 (Compound Types) Scala ひと巡り シーケンス内包表記 (Sequence Comprehensions) Scala ひと巡り 抽出子オブジェクト (Extractor Objects) Scala ひと巡り ジェネリッククラス (Generic Classes) Scala ひと巡り 暗黙のパラメータ (Implicit Parameters) Scala ひと巡り 内部クラス (Inner Classes) Scala ひと巡り ミックスインクラス合成 (Mixin Class Composition) Scala ひと巡り 関数のネスト (Nested Functions) Scala ひと巡り 無名関数の構文 (Anonymous Function Syntax) Scala ひと巡り カリー化 (Currying) Scala ひと巡り 型依存クロージャの自動構築 (Automatic Type-Dependent Closure Construction) Scala ひと巡り オペレータ (Operators) Scala ひと巡り 高階関数 (Higher-Order Functions) Scala ひと巡り パッケージ (Packages) Scala ひと巡り パターンマッチング (Pattern matching) Scala ひと巡り 多相的メソッド (Polymorphic Methods) Scala ひと巡り 正規表現パターン (Regular Expression Patterns) Scala ひと巡り sealed クラス (Sealed Classes) Scala ひと巡り トレイト (Traits) Scala ひと巡り 上限 型境界 (Upper Type Bounds) Scala ひと巡り 下限 型境界 (Lower Type Bounds) Scala ひと巡り 明示的に型付けられた自己参照 (Explicitly Typed Self References) Scala ひと巡り サブクラス化 (Subclassing) Scala ひと巡り ローカルな型推論 (Local Type Inference) Scala ひと巡り 統合された型 (Unified Types) Scala ひと巡り 変位指定 (Variances) Scala ひと巡り ビュー (Views) Scala ひと巡り XML 処理 (XML Processing) 先頭 次 名前 コメント