Skip to content

Instantly share code, notes, and snippets.

@seraphr
Created July 12, 2015 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save seraphr/5e0b178a6c4f42015956 to your computer and use it in GitHub Desktop.
Save seraphr/5e0b178a6c4f42015956 to your computer and use it in GitHub Desktop.
fp in scala EXERCISE 5.11 5.12 5.13 5.14 5.16 unfold関係+scanRight
def unfold[A, S](s: S)(f: S => Option[(A, S)]): Stream[A] = f(s) match {
case Some((a, s1)) => a #:: unfold(s1)(f)
case _ => Stream.empty[A]
}
def fibs: Stream[Int] = 0 #:: 1 #:: unfold((0, 1)) {
case (n0, n1) =>
val n2 = n0 + n1
Option((n2, (n1, n2)))
}
def from(n: Int): Stream[Int] = unfold(n)(a => Some((a, a + 1)))
def constant[A](n: A): Stream[A] = unfold(n)(a => Some((a, a)))
def ones: Stream[Int] = constant(1)
def map[A, B](s: Stream[A])(f: A => B): Stream[B] = unfold(s) {
case x #:: xs => Some((f(x), xs))
case _ => None
}
def take[A](s: Stream[A])(n: Int): Stream[A] = unfold((n, s)) {
case (0, _) => None
case (n, x #:: xs) => Some((x, (n-1, xs)))
case _ => None
}
def takeWhile[A](s: Stream[A])(f: A => Boolean): Stream[A] = unfold(s) {
case x #:: xs if f(x) => Some((x, xs))
case _ => None
}
def zipWith[A, B, C](s1: Stream[A], s2: Stream[B])(f: (A, B) => C): Stream[C] = unfold((s1, s2)) {
case (x #:: xs, y #:: ys) => Some(f(x, y), (xs, ys))
case _ => None
}
def zipAll[A, B](s1: Stream[A], s2: Stream[B]): Stream[(Option[A], Option[B])] = unfold((s1, s2)) {
case (x #:: xs, y #:: ys) => Some((Some(x), Some(y)), (xs, ys))
case (_, y #:: ys) => Some((None, Some(y)), (Stream.empty, ys))
case (x #:: xs, _) => Some((Some(x), None), (xs, Stream.empty))
case _ => None
}
def startsWith[A](s: Stream[A], start: Stream[A]): Boolean = zipAll(s, start).forall {
case (l, r) => l.isDefined && (l == r || r.isEmpty)
}
def scanRight[A, B](s: Stream[A])(z: => B)(f: (A, =>B) => B): Stream[B] = s match {
case x #:: xs =>
lazy val tTails = scanRight(xs)(z)(f)
f(x, tTails.head) #:: tTails
case _ => Stream(z)
}
def tails[A](s: Stream[A]): Stream[Stream[A]] = scanRight(s)(Stream.empty[A])(_ #:: _)
fibs.take(10)
from(10).take(10)
constant("hoge").take(4)
ones.take(3)
map(from(2))(_ * 2).take(5)
take(from(11))(5)
takeWhile(from(0))(_ <= 5)
zipWith(constant("fuga"), from(0).take(10))(_ + _)
zipAll(from(1).take(5), from(2).take(3))
zipAll(from(1).take(3), from(2).take(5))
startsWith(from(1).take(10), from(1).take(4)).ensuring(_ == true)
startsWith(from(1).take(10), from(1).take(14)).ensuring(_ == false)
startsWith(from(1).take(10), from(2).take(4)).ensuring(_ == false)
tails(from(10).take(5))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment