LoginSignup
1
1

More than 1 year has passed since last update.

Scalaの勉強はじめました 11 〜関数型プログラミング編 〜

Posted at

はじめに

N予備校で「Scala応用」コースを受講しています。

ストリーム

Stream2.13以降のバージョンでは非推奨になってい流ので、LazyListを使うこと。

先頭の要素 head と その後ろの要素 tail で構成されるコンスで表現される。

val s = 1 #:: 2 #:: 3 #:: 4 #:: Stream.empty
// => Stream(1, ?)

最初の値は判明しているが、その後ろに何が入っているかはわからない。添字でのアクセスは可能。

無限ストリーム

val eights: Stream[Int] = 8 #:: eights

再帰的に 8 を延々と追加する。
添字でどこを取り出しても 8 が返る。

等差数列

val s = Stream.iterate(1){
  n =>
    println("Calculate! 3 + " + n)
    3 + n
}
// s(1) => 1
// s(2) => 4
// s(3) => 7

実際に評価することで そこまでの再帰呼び出しのデータを生成する仕組みを「余再帰」という。

// 1回目の呼び出し
s(10) => 3 + 1, 3 + 4,......
// 2回目以降
s(10) => 31

途中の計算結果も含め全ての計算結果がストリームの中で保持されている。

lazyキーワード

一度値が評価取得されると、二度目は前の結果を使い回す。

実際の使い所は迷いそう。

implicit キーワード

同じスコープの別の場所で宣言をしておけば コードの実行箇所では宣言しなくても、型変換や引数への代入処理を 自動的に行ってくれる。

import scala.language.implicitConversions

implicit def intToBoolean(arg: Int): Boolean = arg != 0

数値型をBoolean型に暗黙的に変換する。

if(1) println("1はTrueだよ")

implicit def メソッド名(引数名: 引数の型): 返り値の型 = 本体

このメソッドの引数の型の式が現れた時に、 返り値の型を暗黙の候補として登録できる。

文字列の最後に:-)を追加するメソッド

class RichString(val src: String) {
  def smile: String = src + ":-)"
}

implicit def enrichString(arg: String): RichString = new RichString(arg)

// 呼び出し
"Hi, ".smile
// => Hi, :-)

既存のクラスを拡張したように見せかけることができる。

引数の省略

object HTTTravel {
  class Travel {
    def AzuCat(HTT: String): Unit = println(s"${HTT}、アズキャットいて。")
  }

  def member(name: String)(implicit travel: Travel): Unit = travel.AzuCat(name)  
}

// 呼び出し
implicit val HTT = new HTTTravel.Travel
HTTTravel.member("あずにゃん")

なんかもっとうまい例が書けたらよかった

まとめ

lazyimplicitについて、言いたいことはわかるけれどいざ書けって言われるとちょっと自信がない。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1