Created
June 6, 2020 03:09
-
-
Save roshane/d0cdc7b226bf48613f37450d58c3f27a to your computer and use it in GitHub Desktop.
Cousera Reactive Programming Generators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.aeon | |
trait Generator[+T] { | |
self => | |
def generate: T | |
def map[S](f: T => S): Generator[S] = new Generator[S] { | |
def generate = f(self.generate) | |
} | |
def flatMap[S](f: T => Generator[S]): Generator[S] = new Generator[S] { | |
def generate = f(self.generate).generate | |
} | |
} | |
object Chapter01 extends App { | |
val random = new java.util.Random(System.currentTimeMillis()) | |
val numberGenerator = new Generator[Int] { | |
def generate = random.nextInt() | |
} | |
def booleans: Generator[Boolean] = for (i <- numberGenerator) yield i > 0 | |
/** | |
* Explanation of #24 | |
* numberGenerator.map(n => n>0) | |
* | |
* expand map #8 | |
* | |
* val booleanGenerator: Generator[Boolean] = new Generator[Boolean] { | |
* def generate = (n:Int => n > 0)(numberGenerator.generate) | |
* | |
* } | |
* #32 def generate = (numberGenerator.generate > 0) | |
*/ | |
def pairGenerator[A, B](genA: Generator[A], genB: Generator[B]): Generator[(A, B)] = for { | |
va <- genA | |
vb <- genB | |
} yield (va, vb) | |
/** | |
* Explanation of #38 | |
* genA.flatMap(va => genB.map(vb => (va,vb))) | |
* | |
* expand map #40 | |
* genA.flatMap{va => new Generator[(A, B)] { | |
* def generate = (va, genB.generate) | |
* } | |
* | |
* new Generator[(A,B)]{ | |
* def generate = (new Generator[(A,B)]{ | |
* def generate = (genA.generate, genB.generate) | |
* }).generate | |
* } | |
*/ | |
val boolPairGenerator: Generator[(Boolean, Boolean)] = pairGenerator(booleans, booleans) | |
val intPairGenerator: Generator[(Int, Int)] = pairGenerator(numberGenerator, numberGenerator) | |
val intBoolPairGenerator: Generator[(Int, Boolean)] = pairGenerator(numberGenerator, booleans) | |
def lists: Generator[List[Int]] = for { | |
isEmpty <- booleans | |
list <- if (isEmpty) emptyList else nonEmptyList | |
} yield list | |
def single[T](x: T): Generator[T] = new Generator[T] { | |
def generate = x | |
} | |
def emptyList = single(Nil) | |
def nonEmptyList = for { | |
head <- numberGenerator | |
tail <- lists | |
} yield head :: tail | |
(1 to 20).map(_ => lists.generate).foreach(println) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment