Skip to content

Instantly share code, notes, and snippets.

@rjsvaljean
Last active September 29, 2017 12:47
Show Gist options
  • Select an option

  • Save rjsvaljean/cc201456e13d8fba8582e2bededb46ba to your computer and use it in GitHub Desktop.

Select an option

Save rjsvaljean/cc201456e13d8fba8582e2bededb46ba to your computer and use it in GitHub Desktop.
State Demo
scala> Stream.iterate(0)(_ + 1)
res1: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res1.take(10).toList
res2: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> case class State[S, A](f: S => (S, A))
defined class State
// fmap = flatmap
scala> def fmap[S, A, B](s: State[S, A])(f: A => State[S, B]): State[S, B] = State[S, B](in => {val (out, a) = s.f(in); f(a).f(out)})
fmap: [S, A, B](s: State[S,A])(f: A => State[S,B])State[S,B]
scala> val incr = State[Int, String](i => (i + 1, i.toString))
incr: State[Int,String] = State($$Lambda$26454/2125543282@555d2017)
scala> def doUntil[S, A, B](s: State[S, A])(p: A => Boolean): State[S, A] = fmap(s)(a => if(p(a)) State(_s => (_s, a)) else doUntil(s)(p) )
doUntil: [S, A, B](s: State[S,A])(p: A => Boolean)State[S,A]
scala> doUntil(incr)(_ == "10")
res3: State[Int,String] = State($$Lambda$26457/418581614@70138c97)
scala> doUntil(incr)(_ == "10").f(1)
res4: (Int, String) = (11,10)
scala> def map[S, A, B](s: State[S, A])(f: A => B): State[S, B] = State[S, B](in => {val (out, a) = s.f(i
n); (out, f(a))})
map: [S, A, B](s: State[S,A])(f: A => B)State[S,B]
scala> def takeWhile[S, A, B](s: State[S, A])(p: S => Boolean): State[S, Seq[A]] = State((in: S) => if (p(in)) fmap(s)(a => map(takeWhile(s)(p))(a +: _)).f(in) else (in, Seq[A]()) )
takeWhile: [S, A, B](s: State[S,A])(p: S => Boolean)State[S,Seq[A]]
scala> takeWhile(incr)(_.toInt < 10)
res5: State[Int,Seq[String]] = State($$Lambda$26467/1221186808@5ac0e211)
scala> takeWhile(incr)(_.toInt < 10).f(0)
res6: (Int, Seq[String]) = (10,List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
scala> def unit[S, A](a: A): State[S, A] = State((s:S) => (s, a))
unit: [S, A](a: A)State[S,A]
scala> def sequence[S, A](ss: Vector[State[S, A]]): State[S, Vector[A]] = if (ss.isEmpty) unit(Vector()) else fmap(ss.head)(a => map(sequence(ss.tail))(a +: _))
sequence: [S, A](ss: Vector[State[S,A]])State[S,Vector[A]]
scala> sequence(Vector.fill(10)(incr)).f(0)
res8: (Int, Vector[String]) = (10,Vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9))
scala> List(1,2,3).foldLeft(0)(_ + _)
res13: Int = 6
scala> def foldLeft[A, Acc](as: List[A])(acc: Acc)(f: (Acc, A) => Acc): Acc = sequence(as.map(a => State((_acc: Acc) => (f(_acc, a),_acc))).toVector).f(acc)._1
foldLeft: [A, Acc](as: List[A])(acc: Acc)(f: (Acc, A) => Acc)Acc
scala> foldLeft(List(1,2,3))(0)(_ + _)
res12: Int = 6
scala> List(1,2,3).scanLeft(0)(_ + _)
res14: List[Int] = List(0, 1, 3, 6)
scala> def scanLeft[A, Acc](as: List[A])(acc: Acc)(f: (Acc, A) => Acc) = {val (x, y) = sequence(as.map(a
=> State((_acc: Acc) => (f(_acc, a),_acc))).toVector).f(acc); y :+ x }
scanLeft: [A, Acc](as: List[A])(acc: Acc)(f: (Acc, A) => Acc)scala.collection.immutable.Vector[Acc]
scala> scanLeft(List(1,2,3))(0)(_ + _)
res16: scala.collection.immutable.Vector[Int] = Vector(0, 1, 3, 6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment