public
Created

Every single freshman CS question in ˜80 lines of Scala

  • Download Gist
recstream.scala
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
import Stream._
 
object Curryfication {
def curry [A,B,C](f:Pair[A,B] C) = (x:A) (y:B) f (x,y)
def uncurry [A,B,C](f: A B C) = (x:Pair[A,B]) f (x._1) (x._2)
}
 
trait Curried[S,R] {
type Fun
def curry : (S R) Fun
}
 
class CurriedDefault {
implicit def ZeroC[S,R] = new Curried[S,R]{
type Fun = S R
def curry = f f
}
}
 
object Curried extends CurriedDefault{
def apply[S,R] (f:S R) (implicit c:Curried[S,R]) : c.Fun =
c.curry(f)
 
implicit def SuccC[T,S,R] (implicit c:Curried[S,R]) =
new Curried[Pair[T,S],R] {
type Fun = T c.Fun
def curry = f x c.curry(y f(x,y))
}
}
 
trait Uncurried [S] {
type Tuple
type Return
def uncurry : S Tuple Return
}
 
 
class UncurriedDefault {
implicit def ZeroUC[S] = new Uncurried[S S]{
type Tuple = S
type Return = S
def uncurry = f f
}
}
 
object Uncurried extends UncurriedDefault{
def apply[S] (f:S) (implicit uc:Uncurried[S]) : uc.Tuple uc.Return =
uc.uncurry(f)
 
implicit def SuccUC[S,R] (implicit uc:Uncurried[R]) =
new Uncurried[S R]{
type Tuple = Pair[S,uc.Tuple]
type Return = uc.Return
def uncurry = f x uc.uncurry(f (x._1)) (x._2)
}
}
 
trait RecStream [S,Base] {
def prod : (S Base) S Pair[Base, S]
def rstream : (S Base) S Stream[Base]
}
 
class RecStreamDefault {
implicit def ZeroRS[S] = new RecStream[S,S] {
def prod = xs ss (ss, xs (ss))
def rstream = xs ss ss #:: rstream (xs) (xs(ss))
}
 
}
 
object RecStream extends RecStreamDefault {
def apply[S,B](f:S B) (implicit rs:RecStream[S,B]): S Stream[B] =
rs.rstream(f)
 
implicit def SuccRS[R,B] (implicit rs:RecStream[R,B]) =
new RecStream[Pair[B,R],B] {
def prod = f a (a._1, rs.prod (y f (a._1,y)) (a._2))
def rstream = f a
a._1 #:: rstream (f) (rs.prod (y f (a._1,y)) (a._2))
}
 
}
 
object Test{
def increaser : Int Stream[Int] =
RecStream((x:Int) x + 1)
 
def fibonacci : Pair[Int,Int] Stream [Int] =
RecStream(x x._1 + x._2)
 
def sumthree (x:Int)(y:Int)(z:Int) = x+y+z
 
// def sumthreestream = RecStream(sumthree)
 
def uncst = Uncurried(sumthree _)
def sumthreestream = RecStream(uncst)
 
def curriedsumthreestream = Curried(sumthreestream)
 
def main(args:Array[String]) = {
fibonacci(0,1).take(10).print
print ("\n")
increaser(0).take(10).print
print ("\n")
increaser(1).take(10).print
print ("\n")
sumthreestream(0,(0,1)).take(10).print
print("\n")
curriedsumthreestream(0)(0)(1).take(10).print
print("\n")
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.