Skip to content

Instantly share code, notes, and snippets.

@roshane
Created June 6, 2020 03:09
Show Gist options
  • Save roshane/d0cdc7b226bf48613f37450d58c3f27a to your computer and use it in GitHub Desktop.
Save roshane/d0cdc7b226bf48613f37450d58c3f27a to your computer and use it in GitHub Desktop.
Cousera Reactive Programming Generators
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