Magnolia Tech

いつもコードのことばかり考えている人のために。

『Scala関数型デザイン&プログラミング』の演習問題をScala3で解く その7

blog.magnolia.tech

まだまだ続きます。

演習問題を解く上で、そもそも既存のメソッドの挙動がよく分からない、みたいな時はこのサイトが参考になります。

superruzafa.github.io

純粋関数型の状態

テストコード

この章で扱うState[S, +A]や、Rand[A]の関数群は、最終的にはシードであるRNGを引数に取り、生成された値と、新しいシードのタプルを返す関数を返す、という構成になっています。

つまり、最後はシード値を与えて得られた結果を期待値と比較してテスト結果を確認する、という形式になります。

例えばこのようなテストになります。

test("nonNegativeInt") {
  val rng1 = RNG.Simple(42)
  val (a, rng2) = RNG.nonNegativeInt(rng1)

  (a > 0 && r1 != r2) shouldBe true
}

しかし、シード値が一つだけでは不安です。そこで、後ろの章で紹介されるScalaCheckを使うとさまざまなシード値を元にテストができます。これだけで100個のシード値に対するテストができたことになります。

test("nonNegativeInt") {
  forAll { (i:Int) =>
    val rng1 = RNG.Simple(i)
    val (a, rng2) = RNG.nonNegativeInt(rng1)

    (a > 0 && r1 != r2) shouldBe true
  }
}

この後の章でScalaCheckライクなライブラリを書くことになるので、この段階でぜひ挙動を覚えておきましょう。

mapと、map2と、flatMap

この章から意識的に、flatMapと、mapmap2の関係について強調されるようになってきます。この段階でflatMapがあればmapmap2が実装できることをしっかり学んでおきましょう。

lens

FP in ScalaWikilensというライブラリがあることが紹介されています。

aoino.hatenablog.com

自動販売機のシミュレータの演習問題では、いわゆる状態のgetterや、setterが出てきましたが、ネストが深いデータ構造にも適用できるようにするためのライブラリだそうです。