Types
Falcon 9
Rocket Software
object RocketWithVals { case class Rocket( o: O2, f: Fuel ) sealed trait O2 case object NoO2 extends O2 case object HasO2 extends O2 sealed trait Fuel case object NoFuel extends Fuel case object Fueled extends Fuel def createRocket() = Rocket(NoO2, NoFuel) //> createRocket: ()RocketWithVals.Rocket def addFuel(x: Rocket) = x match { case Rocket(o, NoFuel) => Rocket(o, Fueled) case _ => throw new IllegalStateException } //> addFuel: (x: RocketWithVals.Rocket)RocketWithVals.Rocket def addO2(x: Rocket) = x match { case Rocket(NoO2, f) => Rocket(HasO2, f) case _ => throw new IllegalStateException } //> addO2: (x: RocketWithVals.Rocket)RocketWithVals.Rocket def launch(x: Rocket) = x match { case Rocket(HasO2, Fueled) => "launched!" case _ => throw new IllegalStateException } //> launch: (x: RocketWithVals.Rocket)String val goodSeq = launch(addO2(addFuel(createRocket))) //> goodSeq : String = launched! val anotherGoodSeq = launch(addFuel(addO2(createRocket))) //> anotherGoodSeq : String = launched! // val badSeq = launch(addFuel(createRocket())) // val anotherBadSeq = launch(addFuel(addO2(addFuel(createRocket())))) }
Elon does not like the exceptions.
Found http://james-iry.blogspot.com.au
Better Rocket Software
object RocketWithTypes { case class Rocket[ O <: O2, F <: Fuel ]() sealed trait O2 trait NoO2 extends O2 trait HasO2 extends O2 sealed trait Fuel trait NoFuel extends Fuel trait Fueled extends Fuel def createRocket() = Rocket[NoO2, NoFuel] //> createRocket: ()RocketWithTypes.Rocket[RocketWithTypes.NoO2,RocketWithTypes. //| NoFuel] def addFuel[O <: O2](x: Rocket[O, NoFuel]) = Rocket[O, Fueled] //> addFuel: [O <: RocketWithTypes.O2](x: RocketWithTypes.Rocket[O,RocketWithTyp //| es.NoFuel])RocketWithTypes.Rocket[O,RocketWithTypes.Fueled] def addO2[F <: Fuel](x: Rocket[NoO2, F]) = Rocket[HasO2, F] //> addO2: [F <: RocketWithTypes.Fuel](x: RocketWithTypes.Rocket[RocketWithTypes //| .NoO2,F])RocketWithTypes.Rocket[RocketWithTypes.HasO2,F] def launch(x: Rocket[HasO2, Fueled]) = "launched!" //> launch: (x: RocketWithTypes.Rocket[RocketWithTypes.HasO2,RocketWithTypes.Fue //| led])String val goodSeq = launch(addO2(addFuel(createRocket))) //> goodSeq : String = launched! val anotherGoodSeq = launch(addFuel(addO2(createRocket))) //> anotherGoodSeq : String = launched! // val badSeq = launch(addFuel(createRocket())) // val anotherBadSeq = launch(addFuel(addO2(addFuel(createRocket())))) }
Elon likes the type safety.
You can!
JSON Parse State as a type (its recursive)
sealed trait JState trait Start extends JState trait Complete extends JState trait OpenArray[E <: JState] extends JState trait OpenObject[E <: JState] extends JState
Typesafe JSON Incremental JSON Builder
case class JBuilder[S <: JState]( buffer: B, delimit: B => B) { def flip(b: B = empty) = (buffer, JBuilder[S](b, delimit)) def fullText(implicit bufRep: JSONRep[B]) = bufRep fullText buffer } implicit class ArrayOps[E <: JState](b: JBuilder[OpenArray[E]]) { def | [T:Element] (t: T) = shift(Element[T] encode t) ... } implicit class ObjectOps[E <: JState]( b: JBuilder[OpenObject[E]]) { def | [T:Element](f: (String, T)) = shift(f._1, Element[T] encode f._2) ... }
Incremental JSON Generation
object json_generator { import au.com.langdale.json.DSL._ val p1 = JBuilder.start | array | 30.0 //> p1 : au.com.langdale.json.DSL.JBuilder[au.com.langdale.json.DSL.OpenArray[a //| u.com.langdale.json.DSL.Complete]] = JBuilder(List(30.0, [),<function1>) val p2 = p1 | obj | "name" -> "joe" //> p2 : au.com.langdale.json.DSL.JBuilder[au.com.langdale.json.DSL.OpenObject[ //| au.com.langdale.json.DSL.OpenArray[au.com.langdale.json.DSL.Complete]]] = JB //| uilder(List("joe", :, "name", {, ,, 30.0, [),<function1>) // val p3 = p2 | "element" p2.fullText //> res0: CharSequence = [30.0,{"name":"joe" val p4 = p2 | end | end //> p4 : au.com.langdale.json.DSL.JBuilder[au.com.langdale.json.DSL.Complete] = //| JBuilder(List(], }, "joe", :, "name", {, ,, 30.0, [),<function1>) p4.fullText //> res1: CharSequence = [30.0,{"name":"joe"}] }