プログラミング言語 Scala Wiki内検索 / 「Example10.4」で検索した結果

検索 :
  • Example10.4
    10.4 For ループ for 内包表記は命令型言語の for ループに似ていますが、結果のリストを生成します。時には、結果のリストはいらないがリストに対するジェネレータとフィルタの柔軟性が欲しいことがあります。これは for 内包表記の変種、for ループで表現できます。 for ( s ) e この構文は標準的な for 内包表記と同じですが、キーワード yield がありません。for ループは、ジェネレータとフィルタの列 s から生成される各要素に対して、式 e を実行します。 例として、次の式はリストのリストとして表現される行列の全要素を表示します。 for (xs - xss) { for (x - xs) print(x + "\t") println() } for ループから...
  • Example10.2
    10.2 For 内包表記によるクエリ (Querying with For-Comprehensions) for 内包表記は、データベースのクエリ言語による一般的操作と本質的に同じです。たとえば、データベース books があり、本のリストとして表現されているとしましょう。ただし Book は次のように定義されるものとします。 case class Book(title String, authors List[String]) 次はデータベースの小さなサンプルです。 val books List[Book] = List( Book("Structure and Interpretation of Computer Programs", List("Abelson, Haro...
  • Example10.3
    10.3 For 内包表記の変換 すべての for 内包表記は3つの高階関数 map, flatMap, filter で表現できます。これが翻訳のスキーム(枠組み)であり、Scala コンパイラも使っています。 • 単純な for 内包表記 for (x - e) yield e これは次のように翻訳されます。 e.map(x = e ) • for 内包表記 for (x - e if f; s) yield e ただし f はフィルタで、s は (空でも良い) ジェネレータあるいはフィルタの列。これは次のように翻訳されます。 for (x - e.filter(x = f); s) yield e そして後者の式に対して翻訳が続きます。 • for 内包表記 ...
  • Example17.1
    17.1 シグナルとモニター (Signals and Monitors) Example 17.1.1  モニター は Scala におけるプロセスの相互排他処理の基本的な手段を提供します。 AnyRef クラスの各インスタンスは、次の1つあるいは複数のメソッドを呼ぶことでモニターとして使えます。 def synchronized[A] (e = A) A def wait() def wait(msec Long) def notify() def notifyAll() 同期メソッドは相互排他的に、つまり同時にはただ1つのスレッドだけが与えられたモニターの同期化引数を実行できる方式で、その引数である計算 e を実行します。 スレッドはシグナルをウェイトすることで、モニター内でサスペンドできます。 wait...
  • Example4.3
    d#co(){ 4.3 Conditional Expressions Scala s if-else lets one choose between two alternatives. Its syntax is like Java s if-else. But where Java s if-else can be used only as an alternative of statements, Scala allows the same syntax to choose between two expressions. That s why Scala s if-else serves also as a substitute for Java s conditional expression ... ? ... .... } 4.3 条件式 S...
  • Example10.1
    10.1 N クィーン問題 (The N-Queens Problem) for 内包表記は組み合わせパズルを解くのに特に役立ちます。そのようなパズルの一つの例が8クイーン問題 標準的なチェス盤に、8個のクイーンをお互いにチェックしない (クイーンは他の駒が同じ行、列、斜めにある時にチェックできます) ように置け、です。この問題の解法を考えますが、一般化してチェス盤を任意の大きさにします。したがって問題は、n個のクイーンを n x n の大きさのチェス盤に置け、となります。 問題を解くには、クイーンは各行に置かなくてはならないことに注意しましょう。ですから、クイーンを各行に置き、その度に新しく置いたクイーンが、すでに置かれた他のクイーンからチェックされないことを確認します。探索の過程において、行 k のどの場所にクイーンを置いても、それが行 1 から行 k-1 までの...
  • Example4.2
    4.2 パラメータ def を使って、パラメータを持った関数を定義できます。たとえば scala def square(x Double) = x * x square (Double)Double scala square(2) unnamed0 Double = 4.0 scala square(5 + 3) unnamed1 Double = 64.0 scala square(square(4)) unnamed2 Double = 256.0 scala def sumOfSquares(x Double, y Double) = square(x) + square(y) sumOfSquares (Double,Double)Double scala sumOfSquares(3, 2 + 2) un...
  • ScalaByExample和訳
    Scala By Example の和訳 第 1 章 はじめに 第 2 章 最初の例 第 3 章 アクターとメッセージによるプログラミング 第 4 章 式と簡単な関数 第 5 章 第一級の関数 第 6 章 クラスとオブジェクト 第 7 章 ケースクラスとパターンマッチング 第 8 章 ジェネリックな型とメソッド 第 9 章 リスト 第 10 章 For内包表記 第 11 章 ミュータブルな状態 第 12 章 ストリームによる計算 第 13 章 イテレータ 第 14 章 遅延評価val 第 15 章 暗黙の引数と変換 第 16 章 Hindley/Milner 型推論 第 17 章 並列処理の抽象 和訳 PDFはここです reStr...
  • Example4.1
    4.1 式と簡単な関数 Scala システムには、素敵な計算機と見ることのできるインタプリタが同梱されています。ユーザーは式をタイプすることで計算機と交信できます。計算機は評価した結果とその型を返します。たとえば scala 87 + 145 unnamed0 Int = 232 scala 5 + 2 * 3 unnamed1 Int = 11 scala "hello" + " world!" unnamed2 java.lang.String = hello world! 部分式に名前を付け、以後は式の代わりにその名前を使うこともできます。 scala def scale = 5 scale Int scala 7 * scale unnamed3 Int = 35 ...
  • Example10.5
    10.5 For の一般化 (Generalizing For) for 内包表記の翻訳が、メソッド map、flatMap、filter の存在だけに依存していることを見てきました。したがって、リスト以外のオブジェクトを生成するジェネレータについても、同じ記法を適用できます。それらのオブジェクトは3つのキーとなる関数 map、flatMap、filter だけをサポートすればよいのです。 標準 Scala ライブラリには、それら3つのメソッドと for 内包表記をサポートする抽象化が他にもいくつかあります。それらのいくつかは後の章で目にするでしょう。プログラマは自分が定義する型について for 内包表記を使えるようにするために、この原則を利用できます。そのような型は、単にメソッド map、flatMap、filter だけが必要なのです。 このことが役に立つ例...
  • Example5.5
    5.5 ここまでの構文 第 4 章と第 5 章では、プリミティブなデータと関数の、式と型を表現する Scalaの構文を扱いました。下記に、それらの文脈自由文法を拡張 Backus-Naur 記法で与えます。 | は選択を、[...] はオプション (0あるいは1回の出現)、{...} は繰り返し (0回以上の出現)を表します。 文字 Scala プログラムは (Unicode) 文字の列です。次の文字セットを区別します。 空白文字。たとえば 、タブ、改行文字 文字。 a - z 、 A - Z 数字。 0 - 9 区切り文字。 . , ; ( ) { } [ ] \ " 演算子文字。たとえば # + 。正確には、上記のどれにも含まれない印刷可能...
  • Example7.2
    7.2 パターンマッチング (Pattern Matching) パターンマッチングは C や Java の switch 文をクラス階層に一般化したものです。switch 文の代わりに標準メソッド match があり、それは Scala のルートクラス Any で定義されていて、したがって全てのオブジェクトで使用できます。match メソッドは引数として複数のケースを取ります。たとえば、次はパターンマッチングを用いた eval の実装です。 def eval(e Expr) Int = e match { case Number(n) = n case Sum(l, r) = eval(l) + eval(r) } この例では,2つのケースがあります。各ケースはパターンと式を関連付けます。パターンはセレクタ値 e に対してマッチされます。この...
  • Example8.6
    8.6 関数 (Functions) 関数が第一級クラス値であるという点で Scala は関数型言語です。Scala はすべての値がオブジェクトであるという点でオブジェクト指向言語です。したがって Scala では関数はオブジェクトです。たとえば、型 String から型 Int への関数は、トレイト Function1[String, Int] のインスタンスとして表現されます。Function1 トレイトは次のように定義されます。 package scala trait Function1[-A, +B] { def apply(x A) B } Function1 の他にも、異なるすべてのアリティ(項数)の関数に対して,定義があります (現在は、適正値までしか実装されていません) 。つまり、関数のパラメータの数ごとに定義があるということで...
  • Example11.3
    11.3 高度な例 離散イベントシミュレーション(Extended Example Discrete Event Simulation) 代入と高階関数がどのように興味深い形で結びつくか、例をとおして考えます。ここでは、デジタル回路シミュレータを構築します。 この例は Abelson と Sussman の本[ASS96]から借りました。彼らの基本的な (Scheme の) コードを、継承でコードを再利用できるオブジェクト指向によって拡張しています。この例は、一般的な離散イベントのシミュレーションプログラムが、どのように構造化され構築されるかも示します。 デジタル回路を記述する小さな言語から始めます。デジタル回路は 結線 と function box から構築されます。結線は信号を運び、function box は信号を変換します。信号は ture と ...
  • CodeOfScalaByExample
    Scala By Example のコード Chapter 2 Chapter 2 の Quicksort
  • Example11.2
    11.2 命令型制御構造 (Imperative Control Structures) Scala には C や Java で知られる while や do-while のループ構文があります。また else-節のない片側の if や、関数を途中で中止する return 文もあります。これらを使えば、従来の命令型スタイルのプログラミングも可能です。たとえば次の関数は、与えられたパラメータ x の n 乗を計算しますが、while と片側 if を使って実装されています。 def power(x Double, n Int) Double = { var r = 1.0 var i = n var j = 0 while (j 32) { r = r * r if (i 0) r *= x i...
  • Example17.5]
    17.5 Semaphores 17.5 セマフォ A common mechanism for process synchronization is a lock (or semaphore). A lock offers two atomic actions acquire and release. Here s the implementation of a lock in Scala プロセス同期の一般的なメカニズムはロック(あるいはセマフォ)です。ロックは2つのアトミックなアクションを提供します。すなわち、獲得と解放です。次は Scala におけるロックの実装です。 package scala.concurrent class Lock { var available = true def acquire = syn...
  • Example5.3
    5.3 例 関数の不動点探索 数 x は次の条件を満たす時に、関数 f の 不動点 と呼ばれます。 f(x) = x . いくつかの関数 f では、初期推定値から始めて、値が変化しなくなる (あるいは変化が小さな許容量以下になる) まで f を繰り返し適用することで不動点を求めることができます。それは、数列 x, f(x), f(f(x)), f(f(f(x))), ... が、f の不動点に収束すれば可能です。このアイデアを取り入れたのが次の「不動点を求める関数」です。 val tolerance = 0.0001 def isCloseEnough(x Double, y Double) = abs((x - y) / x) tolerance def fixedPoint(f Double = Double)(...
  • Example17.4
    17.4 並列計算 次の例では、関数 par は計算のペアをパラメータとしてとり、計算結果を別のペアで返します。2つの計算は並列実行されます。 この関数はオブジェクト scala.concurrent.ops において、次のように定義されています。 def par[A, B](xp = A, yp = B) (A, B) = { val y = new SyncVar[B] spawn { y set yp } (xp, y.get) } 同じ場所で replicate 関数が定義されていて、多数の計算の複製を並列実行しま す。各複製インスタンスには、それを識別する整数値が渡されます。 def replicate(start Int, end Int)(p Int = ...
  • Example17.10
    17.10 メールボックス メールボックスはプロセス同期と通信のための、高度で柔軟な構造物です。メッセージの送受信が可能です。ここで メッセージ とは任意のオブジェクトを指します。シグナルのタイムアウトに使う TIMEOUT という特別のメッセージがあります。 case object TIMEOUT メールボックスは次のシグネチャを実装します。 class MailBox { def send(msg Any) def receive[A](f PartialFunction[Any, A]) A def receiveWithin[A](msec Long)(f PartialFunction[Any, A]) A } メールボックスの状態はメッセージのマルチセットから成ります。メッセージは ...
  • Example17.9
    17.9 ワーカー Scala における 計算サーバー の実装例を見てみましょう。サーバーは future メソッドを実装し、与えられた式をその呼び出し者と並列に評価します。 17.3節の実装とは異なり、サーバーはスレッドの事前定義された数字だけを持って future を計算します。サーバーの一つのあり得る実装では、別々のプロセッサ上で各スレッドを走らせることができ、シングルプロセッサ上で複数のスレッドを切り替える際のコンテキストスイッチングに伴うオーバーヘッドを回避できます。 import scala.concurrent._, scala.concurrent.ops._ class ComputeServer(n Int) { private abstract class Job { type T def task T...
  • Example13.1
    13.1 イテレータメソッド (Iterator Method) イテレータは、next と hasNext のほかにも豊富なメソッドをサポートしており、それを次で説明します。それらメソッドの多くは、リスト機能の対応するものに似ています。 Append  メソッド append は、新しいイテレータを構築します。構築されるイテレータは、元のイテレータの最後まで到達すると、与えられたイテレータで継続します。 def append[B A](that Iterator[B]) Iterator[B] = new Iterator[B] { def hasNext = Iterator.this.hasNext || that.hasNext def next = if (Iterator.this.hasNext)...
  • Example13.2
    13.2 イテレータの構築 (Constructing Iterators) 具体的なイテレータは、クラス Iterator の2つの抽象メソッド next と hasNext の実装を提供する必要があります。もっとも単純なイテレータは、常に空の列を返す Iterator.empty です。 object Iterator { object empty extends Iterator[Nothing] { def hasNext = false def next = error("next on empty iterator") } もっと面白みのあるイテレータは、配列のすべての要素を列挙するものです。このイテレータはオブジェクト Iterator で定義されている fromArray メソッド...
  • Example4.4
    4.4 例 ニュートン法による平方根計算 ここまでに紹介した構文を、もう少し興味深いプログラムを組み立てて、示しましょう。課題は x の平方根を計算する関数 def sqrt(x Double) Double = ... を書くことです。 平方根を計算する一般的な方法は、近似を繰り返すニュートン法です。まず初期推定値 y (たとえば y=1) から始めます。次いで現在の推定値 y を、y と x/y の平均値を取って繰り返し改良します。次の例では √2 を近似する、推定値 y、商 x/y、その平均が3列に示されています。 1 2/1 = 2 1.5 1.5 2/1.5 = 1.3333 1.4167 1.4167 2/1...
  • Example11.4
    11.4 まとめ この章では、Scala において状態をモデル化する手段 --- 変数、代入、そして手続き的な制御構造 --- を見てきました。状態と代入は、計算に関する我々のメンタルモデルを複雑にします。特に、参照透過性は失われます。一方で、代入はプログラムをエレガントに書く新しい方法を提供します。いつものことですが、純粋関数型プログラミングと代入を使うプログラミングの、どちらがベストであるかは状況によります。 前ページ 11 章 目次 次ページ 名前 コメント
  • Example8.4
    8.4 最下層の型 (Least Types) Scala では、オブジェクトを型でパラメータ化することはできません。そういう訳で、たとえ任意の型の空スタックを表すただ一つの値で充分だったとしても、最初にジェネリッククラス EmptyStack[A] を定義しました。しかし、共変的スタックについては、次のイディオムを使えます。 object EmptyStack extends Stack[Nothing] { ... } ボトム型 Nothing は値を持ちません。したがって型 Stack[Nothing] は、EmptyStack が要素を含まないことを表現します。さらに、Nothing は他のすべての型のサブタイプです。ですから、共変的スタックではどんな型 T に対しても、Stack[Nothing] は Stack[T] のサブタイプです。これによってユ...
  • Example11.1
    11.1 状態を持つオブジェクト (Stateful Object) 我々は世界をオブジェクトの集合としてとらえ、オブジェクトの中には時間と共に変化する状態を持つものもあります。通常、状態は計算の過程で変化しうる変数の集合と結びついています。プログラミング言語の特定の構文に触れずに、状態を抽象化して言うと、「もしオブジェクトの振る舞いがその履歴に影響されるなら、オブジェクトは 状態を持つ ( ステートフル である)。」となります。 たとえば、銀行口座オブジェクトは状態を持ちます。なぜなら「100スイスフラン引き出せるか?」は口座の存続期間、異なる答を持ちうるからです。 Scala ではすべてのミュータブルな状態は、結局のところ、変数から作られます。変数定義は値定義と同じように書きますが、val の代わりに var で始まります。たとえば、次の2つの定義は2つの...
  • Example9.4
    9.4 リストクラスの定義Ⅱ 高階メソッド ここまでに見た例が示すことは、リストに対する関数はしばしば似た構造をしているということです。リストに対する計算パターンをいくつか見ることができます。たとえば、 ある方法で全ての要素を変換する 条件を満たす全ての要素を取り出す。 ある演算子を用いて全ての要素を結合する 関数型プログラミング言語では高階関数を使うことで、パターンを実装する汎用的な関数を書けます。よく使われる高階関数について議論しますが、それらはクラス List のメソッドとして実装されています。 リストのマッピング  リストの各要素を変換して結果のリストを得ることは、よくある操作です。たとえば、リストの各要素を与えられた数だけ倍するのは、 def scaleList(xs List[Double], facto...
  • Example17.3
    17.3 フューチャー フューチャー は、他のクライアントスレッドにおいて並列に計算される値であり、クライアントスレッドによっていつか使用されます。フューチャーは並行プロセスのリソースを有効に利用するために使います。典型的な使い方は次のようです。 import scala.concurrent.ops._ ... val x = future(someLengthyComputation) anotherLengthyComputation val y = f(x()) + g(x()) future メソッドはオブジェクト scala.concurrent.ops において、次のように定義されています。 def future[A](p = A) Unit = A = { val result = new SyncVar[A]...
  • Example17.7
    17.7 非同期チャネル プロセス内通信の基本的な方法には非同期チャネルがあります。その実装では次の単純な連結リストを利用しています。 class LinkedList[A] { var elem A = _ var next LinkedList[A] = null } 連結リストへの要素の挿入・追加を助けるために、連結リストの中への参照はすべて、リストの先頭を概念的に表すノードの手前のノードを指します。空きの連結リストはダミーノードで始まり、次の要素は nullです。 チャネルクラスは、送られたがまだ読み出されていないデータを保持するのに連結リストを使います。反対の端では、空きのチャネルから読み出そうとするスレッドは nreaders フィールドをインクリメントすることで自分を登録し、通知されるのを待ちます。 packa...
  • Example13.3
    13.3 イテレータの使用 イテレータの使い方の例をさらに2つあげます。最初は、配列 xs Array[Int]のすべての要素を表示するもので、次のように書けます。 Iterator.fromArray(xs) foreach (x = println(x)) または for 内包表記を使っても書けます。 for (x Iterator.fromArray(xs)) println(x) 二つ目の例として、double の配列のうち、要素がある値より大きいすべてのインデックスを求めることを考えます。インデックスはイテレータとして返されるものとします。これは、次の式で実現できます。 import Iterator._ fromArray(xs) .zip(from(0)) .filter(case (x, i) = x ...
  • Example9.1
    9.1 リストの使用 (Using Lists) リスト型  配列と同じくリストは 等質 です。つまり、リストの要素はすべて同じ型です。要素型 T のリストの型は List[T] と書きます(Java の T[] は配列です)。 val fruit List[String] = List("apples", "oranges", "pears") val nums List[Int] = List(1, 2, 3, 4) val diag3 List[List[Int]] = List(List(1, 0, 0), List(0, 1, 0), List(0, 0, 1)) val empty List[Int] = List() リストのコンストラクタ  すべてのリストは2つの...
  • Example17.6
    17.6 リーダー/ライター より複雑な同期の形態では、共通リソースを変更することなくアクセスする リーダー と、アクセスと変更の両方が可能な ライター を区別します。リーダーとライターを同期させるために startRead、startWrite、endRead、endWrite、その他を実装する必要があります。 多数の並行リーダーがある 同時にはただ1つのライターのみ可能 ペンディング中の書き込み要求は、ペンディング中の読み込み要求よりも優先するが、実行中のリード操作をプリエンプトしない 次のリーダー/ライター ロックの実装は メールボックス に基づいています (17.10節参照)。 import scala.concurrent._ class ReadersWriters { val m = new MailBox...
  • Example8.5
    8.5 タプル (Tuples) 関数から1つ以上の結果を返す必要がたまに生じます。たとえば、与えられた2つの整数引数の整数商と余りを返す関数 divmod を考えましょう。もちろん、divmod の2つの結果を保持するクラスを次のようにも定義できます。 case class TwoInts(first Int, second Int) def divmod(x Int, y Int) TwoInts = new TwoInts(x / y, x % y) しかし、結果型のペア一つ一つに対し、新しいクラスを定義しなくてはならないのでは、あまりに面倒です。Scala ではその代わりに、次のように定義されたジェネリッククラス Tuple2 を使えます。 package scala case class Tuple2[A, B](_1 A, _2...
  • ExampleChap6
    第 6 章 クラスとオブジェクト Scala には組み込みの有理数型はありませんが、クラスを使って簡単に定義できます。次が実装例です。 class Rational(n Int, d Int) { private def gcd(x Int, y Int) Int = { if (x == 0) y else if (x 0) gcd(-x, y) else if (y 0) -gcd(x, -y) else gcd(y % x, x) } private val g = gcd(n, d) val numer Int = n/g val denom Int = d/g def +(that Rational) = new Rational(numer * that...
  • Example17.5
    17.5 セマフォ プロセス同期の一般的なメカニズムは ロック (あるいは セマフォ ) です。ロックは2つのアトミックなアクションを提供します。すなわち、 獲得 と 解放 です。次は Scala におけるロックの実装です。 package scala.concurrent class Lock { var available = true def acquire = synchronized { while (!available) wait() available = false } def release = synchronized { available = true notify() } } 前ページ 17 章 目次 次ページ ...
  • Example17.2
    17.2 同期変数 同期化された変数(あるいは縮めて、同期変数)は変数の読み出しと設定用に、get と put 操作を提供します。get 操作は、変数が定義されるまでブロックします。unset 操作は、変数を未定義状態にリセットします。 次は同期変数の標準的な実装です。 package scala.concurrent class SyncVar[A] { private var isDefined Boolean = false private var value A = _ def get = synchronized { while (!isDefined) wait() value } def set(x A) = synchronized { value = x; isDefined =...
  • Example17.8
    17.8 同期チャネル 同期チャネルの実装例を見てみましょう。ここではメッセージの送信者はメッセージが受け取られるまでブロックします。同期チャネルは、転送するメッセージを保持するのにただ1つの変数を必要としますが、リーダーとライタープロセスをうまく連動させるために3つの信号を使います。 package scala.concurrent class SyncChannel[A] { private var data A = _ private var reading = false private var writing = false def write(x A) = synchronized { while (writing) wait() data = x writing = true ...
  • Example8.1
    8.1 型パラメータの境界 クラスをジェネリックにする方法を知った今では、前に書いたクラスの中には一般化した方が自然なものがあります。たとえばクラス IntSet は、任意の要素型を持てるように一般化できます。やってみましょう。ジェネリックな集合の抽象クラスは簡単に書けます。 abstract class Set[A] { def incl(x A) Set[A] def contains(x A) Boolean } しかしもし二分木として実装し続けたいなら、問題に直面します。メソッド contains と incl はどちらも、要素をメソッド と を使って比較します。IntSet については、これは OK です。なぜなら Int はそれら2つのメソッドを持っているからです。しかし任意の型パラメータ a に対しては、それは保証でき...
  • Example5.2
    5.2 カリー化 (Curring) 和を求める関数の最後の設計はすでにかなり簡潔です。しかし更に可能です。a と b がすべての関数でパラメータまたは引数として現れる一方で、興味深い組み合わせを成していないようです。それらを除去できるでしょうか。 sum を書き直し、境界 a と b をパラメータにしないようにしましょう。 def sum(f Int = Int) (Int, Int) = Int = { def sumF(a Int, b Int) Int = if (a b) 0 else f(a) + sumF(a + 1, b) sumF } この設計では、sum は他の関数、すなわち特別な和を求める関数 sumF を返す関数です。後者の関数がすべての仕事をします。境界 a と b をパラメータとしてとり...
  • Example7.1
    7.1 ケースクラスとケースオブジェクト ケースクラス と ケースオブジェクト は普通のクラスやオブジェクトのように定義しますが、定義に修飾子 case が手前に付くことだけが違います。たとえば定義 abstract class Expr case class Number(n Int) extends Expr case class Sum(e1 Expr, e2 Expr) extends Expr は、Number と Sum をケースクラスとして導入します。クラスやオブジェクト定義の前の case 修飾子には、次のような効果があります。 1. ケースクラスは暗黙のうちにコンストラクタ関数を伴い、それはクラスと同じ名前です。この例の場合、2つの関数 def Number(n Int) = new Number(n) def ...
  • Example9.2
    9.2 リストクラスの定義Ⅰ 一階メソッド リストは Scala では組み込み型ではありません。抽象クラス List として定義され、2つのサブクラス と Nil があります。以降では、クラス List のツアーに出かけます。 package scala abstract class List[+A] { List は抽象クラスであり、空の List コンストラクタを呼び出して (たとえば new List )、要素を定義することはできません。クラスには型パラメータ a があります。このパラメータについて共変、つまり S T であるような型 S と T について、List[S] List[T] です。クラスはパッケージ scala にあります。このパッケージは Scala の最も重要で標準的なクラスを含んでいます。List は多くのメソッドを定...
  • Example4.5
    4.5 ネストした関数 関数型プログラミングスタイルでは、小さなヘルパー関数をたくさん作ることを推奨しています。先の例では、sqrt の実装はヘルパー関数 sqrtIter、improve、isGoodEnough を使っています。これらの関数の名前は sqrt の実装にだけ関係します。ふつう我々は、sqrt のユーザーがこれらの関数に直接アクセスすることを望みません。 そうすることを (そして名前空間の汚染を避けるのを)、ヘルパー関数を呼び出す関数自身の中へ入れることで強制できます。 def sqrt(x Double) = { def sqrtIter(guess Double, x Double) Double = if (isGoodEnough(guess, x)) guess else sqrtIter(improve(g...
  • Example5.4
    5.4 まとめ 前の章で、関数は抽象化に必須である、なぜなら計算の一般的な方法を明示できるから、ということ、関数は我々のプログラミング言語において名前の付いた要素であることを見てきました。この章では、それら抽象化は高階関数と組み合わせることで、さらに抽象化できることを示しました。プログラマは抽象化と再利用の機会を探すべきです。最大限に抽象化することが必ずしも最適とは限りませんが、適切な場面で抽象化できるように、抽象化の技法を知ることは重要です。 前ページ 5 章 目次 次ページ
  • Example17.11
    17.11 アクター 第 3 章で電子オークションサービスのプログラム実装例をざっと見ました。そのサービスは、パターンマッチングを使ってメールボックス中のメッセージを調べて動く、高度なアクタープロセスに基づいています。アクターの洗練、最適化された実装は scala.actors パッケージに収められています。ここで、アクターライブラリの簡略化バージョンを見てみましょう。 次のコードは scala.actors パッケージの実装とは異なります。アクターの簡略バージョンをどのように実装できるか、の例として見てください。アクターが実際にどのように定義されているか、あるいは標準 Scala ライブラリにおける実装を記述するものではありません。後者については Scala APIドキュメントを参照してください。 簡略化されたアクターは、通信プリミティブがメールボックスのそれ...
  • ExampleChap7
    第 7 章 ケースクラスとパターンマッチング ところで、数式のインタプリタを書きたいとしましょう。はじめは話を単純にするために、単に数と + 演算だけに制限します。そのような式はあるクラス階層、ルートの抽象基底クラス Expr と、2つのサブクラス Number と Sum を用いて表現できます。すると、式 1 + (3 + 7) は次のように表現されます。 new Sum(new Number(1), new Sum(new Number(3), new Number(7))) さて、このような式評価器は、それがどの形式であるか (Sum か Number か) を知る必要があり、式の要素にアクセスする必要もあります。次は必要なメソッドすべての実装です。 abstract class Expr { def isNumber Boolean ...
  • Example8.2
    8.2 変位指定アノテーション (Variance Annotations) 型パラメータとサブタイプ化の組み合わせは興味深い問題を引き起こします。たとえば、Stack[String] は Stack[AnyRef] のサブタイプであるべきでしょうか? 直感的には OK のように思われます。String のスタックは AnyRef のスタックの特別な場合だからです。より一般的に言うと、もし T が型 S のサブタイプなら、Stack[T] は Stack[S] のサブタイプであるべきです。この性質は 共変 (co-variant)サブタイプ化と呼ばれます。 Scala では、ジェネリック型はデフォルトでは非変(non-variant)サブタイプ化です。それは、前に定義した Stack については、異なる要素型のスタックは決してサブタイプ関係にないということです。しかし、ク...
  • Example9.3
    9.3 例 マージソート (Merge sort) この章で前に示した挿入ソートは、書くのは簡単ですがあまり効率的ではありません。その平均的な計算量は入力リストの長さの2乗に比例します。さて、挿入ソートより効率的にリスト要素をソートするプログラムをデザインしましょう。そのためのよいアルゴリズムは マージソート です。次のように動きます。 はじめに、もしリストが0個あるいは1個の要素を持つなら、それはすでにソートされているので、そのままリストを返します。長いリストは2つのサブリストに分割され、それぞれが元のリストの半分の要素を含むようにします。各サブリストはソート関数への再帰呼び出しでソートされ、得られる2つのソート済みリストは、マージ操作にて結合されます。 マージソートを汎用的な実装とするために、ソートされるリストの要素型だけではなく、要素の比較に使う関数も...
  • ExampleChap3
    第 3 章 アクターとメッセージによるプログラミング この章では、ある応用分野の例を見てゆきます。この分野は Scala がとてもよく似合っています。電子オークションサービスを実装する仕事を考えてみて下さい。Erlang 風のアクタープロセスモデルを使ってオークション参加者の実装をしましょう。アクターとはメッセージを受信するオブジェクトです。各アクターはメッセージ受信用の「メールボックス」を持ち、それはキューとして表現されます。メールボックス中のメッセージを順番に処理することも、特定のパターンにマッチするメッセージを検索することもできます。 取引される商品ごとに一つの競売人アクターがあり、そのアクターが、商品についての情報公開、クライアントからの申し込み受付け、取引終了時の売り手および落札者への通知します。ここでは簡単な実装の概要を示します。 最初のステップとし...
  • Example9.5
    9.5 まとめ この章では、リストをプログラミングの基本的なデータ構造として紹介しました。リストはイミュータブル(変更不能)なので、関数型プログラミング言語では一般的なデータ型です。命令型言語における配列に匹敵する役割を持っています。しかし配列とリストではアクセス方法に大きな違いがあります。配列へのアクセスは常にインデックスによりますが、リストではインデックスは滅多に使いません。scala.List にはインデックスによるアクセスのための apply メソッドが定義されていましたが、この操作は配列の場合よりずっとコストがかかります (一定時間に対して線形)。通常、リストはインデックスの代わりに再帰的にアクセスされ、再帰のステップは、たいていの場合、リスト上のパターンマッチに基づきます。また、豊富な高階コンビネータ群により、リストに対する事前定義された計算パターンをインスタンス化でき...
  • @wiki全体から「Example10.4」で調べる

更新順にページ一覧表示 | 作成順にページ一覧表示 | ページ名順にページ一覧表示 | wiki内検索

ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。