2015年6月20日土曜日

scala関数型デザイン&プログラミング P167

Exercise8.10 GenをSGenに変換するヘルパー関数を実装せよ。これはGenのメソッドとして追加できる。 unsized(すべてのサイズに合うという意味)
def unsized: SGen[A] = SGen(_ => this)
なぜ、Intの部分が_でいいのか?

Exercise8.11 当然のことながら、SGenは少なくともGenと同じ演算の多くをサポートし、その実装はかなり機械的である。Genの対応する関数にデリゲートするするだけの便利な関数をSGenで定義せよ。

case class Gen[+A](sample: State[RNG,A]) {
  def map[B](f: A => B): Gen[B] =
    Gen(sample.map(f))

   def flatMap[B](f: A => Gen[B]): Gen[B] =
    Gen(sample.flatMap(a => f(a).sample))

   def **[B](g: Gen[B]): Gen[(A,B)] =
    (this map2 g)((_,_))
}
が、すでにGenの中にあるとして?、のようだ。

case class SGen[+A](g: Int => Gen[A]) {
  def apply(n: Int): Gen[A] = g(n)

  def map[B](f: A => B): SGen[B] =
    SGen(g andThen (_ map f))

  def flatMap[B](f: A => Gen[B]): SGen[B] =
    SGen(g andThen (_ flatMap f))

  def **[B](s2: SGen[B]): SGen[(A,B)] =
    SGen(n => apply(n) ** s2(n))
}
andThenは関数の合成  (_ map f)等は _ =>_ map f ということ?
Genの中では、**は、map2をつかって、AとBを結合して(A,B)にするということのようだ。
これを使って、SGenの中では、 apply(n)がGen[A]で、s2(n)がGen[B]となり、apply(n)**s2(n)が、Gen[(A,B)]となるということ?

Exercise8.12 明示的なサイズを受け取らないListOfコンビネータを実装せよ。この実装は、GenでなくSGenを返し、要求されたサイズのリストを生成する。

def listOf[A](g:Gen[A]):SGen[List[A]] =
  SGen(n => g.listOfN(n))

SGenのイメージがいまいちつかめない

0 件のコメント:

コメントを投稿