diff --git a/build.sbt b/build.sbt index 1a9f98f..3d59512 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,7 @@ lazy val core = (project in file("core")).settings( version := "2.0.0-SNAPSHOT", scalaVersion := "2.13.5", libraryDependencies ++= Seq( - "tf.bug" %% "shinji" % "0.1.6", + "tf.bug" %% "shinji" % "0.1.8", "com.lihaoyi" %% "pprint" % "0.5.6", ), ) diff --git a/core/src/main/scala/tf/bug/fancade/Fanscript.scala b/core/src/main/scala/tf/bug/fancade/Fanscript.scala index 623e5e6..cc4fb62 100644 --- a/core/src/main/scala/tf/bug/fancade/Fanscript.scala +++ b/core/src/main/scala/tf/bug/fancade/Fanscript.scala @@ -5,216 +5,720 @@ import tf.bug.shinji.{Arrow, ArrowLoop, Cartesian, Monoidal} object Fanscript { sealed trait Pin - sealed trait Number extends Pin - sealed trait Bool extends Pin - sealed trait Vector extends Pin - sealed trait Rotation extends Pin - sealed trait Obj extends Pin - sealed trait Constraint extends Pin - sealed trait Pull extends Pin - sealed trait T extends Pin - sealed trait ×[A <: Pin, B <: Pin] extends Pin + case object Number extends Pin + case object Bool extends Pin + case object Vector extends Pin + case object Rotation extends Pin + case object Obj extends Pin + case object Constraint extends Pin + case object Pull extends Pin + case object T extends Pin + case class ×[A <: Pin, B <: Pin](a: A, b: B) extends Pin - sealed trait →[A <: Pin, B <: Pin] - case class Id[A <: Pin]() extends (A → A) - case class AndThen[A <: Pin, B <: Pin, C <: Pin](f: A → B, g: B → C) extends (A → C) - case class Swap[A <: Pin, B <: Pin]() extends ((A × B) → (B × A)) - case class Deunit[A <: Pin]() extends (A → (T × A)) - case class Unit[A <: Pin]() extends ((T × A) → A) - case class Associate[A <: Pin, B <: Pin, C <: Pin]() extends (((A × B) × C) → (A × (B × C))) - case class Duplicate[A <: Pin]() extends (A → (A × A)) - case class Terminate[A <: Pin]() extends (A → T) - case class Bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A → B, g: C → D) extends ((A × C) → (B × D)) - case class Loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)) extends (A → B) + trait PinEv[A <: Pin] { + val value: A + } + object PinEv { + implicit val pinValueForNumber: PinEv[Number.type] = new PinEv[Number.type] { + override val value: Number.type = Number + } + implicit val pinValueForBool: PinEv[Bool.type] = new PinEv[Bool.type] { + override val value: Bool.type = Bool + } + implicit val pinValueForVector: PinEv[Vector.type] = new PinEv[Vector.type] { + override val value: Vector.type = Vector + } + implicit val pinValueForRotation: PinEv[Rotation.type] = new PinEv[Rotation.type] { + override val value: Rotation.type = Rotation + } + implicit val pinValueForObj: PinEv[Obj.type] = new PinEv[Obj.type] { + override val value: Obj.type = Obj + } + implicit val pinValueForConstraint: PinEv[Constraint.type] = new PinEv[Constraint.type] { + override val value: Constraint.type = Constraint + } + implicit val pinValueForPull: PinEv[Pull.type] = new PinEv[Pull.type] { + override val value: Pull.type = Pull + } + implicit val pinValueForT: PinEv[T.type] = new PinEv[T.type] { + override val value: T.type = T + } + implicit def pinValueForProduct[A <: Pin, B <: Pin](implicit left: PinEv[A], right: PinEv[B]): PinEv[A × B] = new PinEv[A × B] { + override val value: A × B = ×(left.value, right.value) + } + } - case object Z extends (T → Pull) + sealed trait →[A <: Pin, B <: Pin] { + def left: A + def right: B + + final def leftEv: PinEv[A] = new PinEv[A] { + override val value: A = left + } + final def rightEv: PinEv[B] = new PinEv[B] { + override val value: B = right + } + + final def andThen[C <: Pin](f: B → C): A → C = + fanscript.andThen(this, f) + final def >>>[C <: Pin](f: B → C): A → C = + andThen(f) + + final def compose[C <: Pin](f: C → A): C → B = + fanscript.compose(this, f) + final def <<<[C <: Pin](f: C → A): C → B = + compose(f) + + final def split[C <: Pin, D <: Pin](f: C → D): (A × C) → (B × D) = + fanscript.split(this, f) + final def ***[C <: Pin, D <: Pin](f: C → D): (A × C) → (B × D) = + split(f) + + final def merge[C <: Pin](f: A → C): A → (B × C) = + fanscript.merge(this, f) + final def &&&[C <: Pin](f: A → C): A → (B × C) = + merge(f) + } + case class Id[A <: Pin](a: A) extends (A → A) { + override def left: A = a + override def right: A = a + } + case class AndThen[A <: Pin, B <: Pin, C <: Pin](f: A → B, g: B → C) extends (A → C) { + override def left: A = f.left + override def right: C = g.right + } + case class Swap[A <: Pin, B <: Pin](a: A, b: B) extends ((A × B) → (B × A)) { + override def left: A × B = ×(a, b) + override def right: B × A = ×(b, a) + } + case class Deunit[A <: Pin](a: A) extends (A → (T.type × A)) { + override def left: A = a + override def right: T.type × A = ×(T, a) + } + case class Unit[A <: Pin](a: A) extends ((T.type × A) → A) { + override def left: T.type × A = ×(T, a) + override def right: A = a + } + case class Associate[A <: Pin, B <: Pin, C <: Pin](a: A, b: B, c: C) extends (((A × B) × C) → (A × (B × C))) { + override def left: (A × B) × C = ×(×(a, b), c) + override def right: A × (B × C) = ×(a, ×(b, c)) + } + case class Duplicate[A <: Pin](a: A) extends (A → (A × A)) { + override def left: A = a + override def right: A × A = ×(a, a) + } + case class Terminate[A <: Pin](a: A) extends (A → T.type) { + override def left: A = a + override def right: T.type = T + } + case class Bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A → B, g: C → D) extends ((A × C) → (B × D)) { + override def left: A × C = ×(f.left, g.left) + override def right: B × D = ×(f.right, g.right) + } + case class Loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)) extends (A → B) { + override def left: A = f.left.a + override def right: B = f.right.a + } + + case object Z extends (T.type → Pull.type) { + override def left: T.type = T + override def right: Pull.type = Pull + } + + def bubbleSort[In <: Pin, Out <: Pin](sort: Vector[Int])(implicit inEv: PinEv[In], outEv: PinEv[Out]): Option[In → Out] = { + ??? + } object Builtin { - case class NumberValue(number: Float) extends (T → Number) - case class VectorValue(x: Float, y: Float, z: Float) extends (T → Vector) - case class RotationValue(x: Float, y: Float, z: Float) extends (T → Rotation) - case object TrueValue extends (T → Bool) - case object FalseValue extends (T → Bool) + case class NumberValue(number: Float) extends (T.type → Number.type) { + override def left: T.type = T + override def right: Number.type = Number + } + case class VectorValue(x: Float, y: Float, z: Float) extends (T.type → Vector.type) { + override def left: T.type = T + override def right: Vector.type = Vector + } + case class RotationValue(x: Float, y: Float, z: Float) extends (T.type → Rotation.type) { + override def left: T.type = T + override def right: Rotation.type = Rotation + } + case object TrueValue extends (T.type → Bool.type) { + override def left: T.type = T + override def right: Bool.type = Bool + } + case object FalseValue extends (T.type → Bool.type) { + override def left: T.type = T + override def right: Bool.type = Bool + } - case object InspectNumber extends ((Number × Pull) → Pull) - case object InspectVector extends ((Vector × Pull) → Pull) - case object InspectRotation extends ((Rotation × Pull) → Pull) - case object InspectTruth extends ((Bool × Pull) → Pull) - case object InspectObject extends ((Obj × Pull) → Pull) + case object InspectNumber extends ((Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Pull.type = ×(Number, Pull) + override def right: Pull.type = Pull + } + case object InspectVector extends ((Vector.type × Pull.type) → Pull.type) { + override def left: Vector.type × Pull.type = ×(Vector, Pull) + override def right: Pull.type = Pull + } + case object InspectRotation extends ((Rotation.type × Pull.type) → Pull.type) { + override def left: Rotation.type × Pull.type = ×(Rotation, Pull) + override def right: Pull.type = Pull + } + case object InspectTruth extends ((Bool.type × Pull.type) → Pull.type) { + override def left: Bool.type × Pull.type = ×(Bool, Pull) + override def right: Pull.type = Pull + } + case object InspectObject extends ((Obj.type × Pull.type) → Pull.type) { + override def left: Obj.type × Pull.type = ×(Obj, Pull) + override def right: Pull.type = Pull + } - case object Win extends (Pull → Pull) - case object Lose extends (Pull → Pull) - case object SetScore extends ((Number × Pull) → Pull) - case object SetCamera extends ((Vector × Rotation × Number × Pull) → Pull) - case object SetLight extends ((Vector × Rotation × Pull) → Pull) - case object ScreenSize extends (T → (Number × Number)) - case object Accelerometer extends (T → Vector) - case object CurrentFrame extends (T → Number) + case object Win extends (Pull.type → Pull.type) { + override def left: Pull.type = Pull + override def right: Pull.type = Pull + } + case object Lose extends (Pull.type → Pull.type) { + override def left: Pull.type = Pull + override def right: Pull.type = Pull + } + case object SetScore extends ((Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Pull.type = ×(Number, Pull) + override def right: Pull.type = Pull + } + case object SetCamera extends ((Vector.type × Rotation.type × Number.type × Pull.type) → Pull.type) { + override def left: Vector.type × Rotation.type × Number.type × Pull.type = ×(×(×(Vector, Rotation), Number), Pull) + override def right: Pull.type = Pull + } + case object SetLight extends ((Vector.type × Rotation.type × Pull.type) → Pull.type) { + override def left: Vector.type × Rotation.type × Pull.type = ×(×(Vector, Rotation), Pull) + override def right: Pull.type = Pull + } + case object ScreenSize extends (T.type → (Number.type × Number.type)) { + override def left: T.type = T + override def right: Number.type × Number.type = ×(Number, Number) + } + case object Accelerometer extends (T.type → Vector.type) { + override def left: T.type = T + override def right: Vector.type = Vector + } + case object CurrentFrame extends (T.type → Number.type) { + override def left: T.type = T + override def right: Number.type = Number + } - case object GetPosition extends (Obj → (Vector × Rotation)) - case object SetPosition extends ((Obj × Vector × Rotation × Pull) → Pull) - case object Raycast extends ((Vector × Vector) → (Bool × Vector × Obj)) - case object GetSize extends (Obj → (Vector × Vector)) - case object SetVisible extends ((Obj × Bool × Pull) → Pull) - case object CreateObject extends ((Obj × Pull) → (Obj × Pull)) - case object DestroyObject extends ((Obj × Pull) → Pull) + case object GetPosition extends (Obj.type → (Vector.type × Rotation.type)) { + override def left: Obj.type = Obj + override def right: Vector.type × Rotation.type = ×(Vector, Rotation) + } + case object SetPosition extends ((Obj.type × Vector.type × Rotation.type × Pull.type) → Pull.type) { + override def left: Obj.type × Vector.type × Rotation.type × Pull.type = ×(×(×(Obj, Vector), Rotation), Pull) + override def right: Pull.type = Pull + } + case object Raycast extends ((Vector.type × Vector.type) → (Bool.type × Vector.type × Obj.type)) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Bool.type × Vector.type × Obj.type = ×(×(Bool, Vector), Obj) + } + case object GetSize extends (Obj.type → (Vector.type × Vector.type)) { + override def left: Obj.type = Obj + override def right: Vector.type × Vector.type = ×(Vector, Vector) + } + case object SetVisible extends ((Obj.type × Bool.type × Pull.type) → Pull.type) { + override def left: Obj.type × Bool.type × Pull.type = ×(×(Obj, Bool), Pull) + override def right: Pull.type = Pull + } + case object CreateObject extends ((Obj.type × Pull.type) → (Obj.type × Pull.type)) { + override def left: Obj.type × Pull.type = ×(Obj, Pull) + override def right: Obj.type × Pull.type = ×(Obj, Pull) + } + case object DestroyObject extends ((Obj.type × Pull.type) → Pull.type) { + override def left: Obj.type × Pull.type = ×(Obj, Pull) + override def right: Pull.type = Pull + } - case class PlaySound(loop: Boolean, sample: SoundSample) extends ((Number × Number × Pull) → (Number × Pull)) - case object StopSound extends ((Number × Pull) → Pull) - case object VolumePitch extends ((Number × Number × Number × Pull) → Pull) + case class PlaySound(loop: Boolean, sample: SoundSample) extends ((Number.type × Number.type × Pull.type) → (Number.type × Pull.type)) { + override def left: Number.type × Number.type × Pull.type = ×(×(Number, Number), Pull) + override def right: Number.type × Pull.type = ×(Number, Pull) + } + case object StopSound extends ((Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Pull.type = ×(Number, Pull) + override def right: Pull.type = Pull + } + case object VolumePitch extends ((Number.type × Number.type × Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Number.type × Number.type × Pull.type = ×(×(×(Number, Number), Number), Pull) + override def right: Pull.type = Pull + } - case object AddForce extends ((Obj × Vector × Vector × Vector × Vector × Pull) → Pull) - case object GetVelocity extends (Obj → (Vector × Vector)) - case object SetVelocity extends ((Obj × Vector × Vector × Pull) → Pull) - case object SetLocked extends ((Obj × Vector × Vector × Pull) → Pull) - case object SetMass extends ((Obj × Number × Pull) → Pull) - case object SetFriction extends ((Obj × Number × Pull) → Pull) - case object SetBounciness extends ((Obj × Number × Pull) → Pull) - case object SetGravity extends ((Vector × Pull) → Pull) - case object AddConstraint extends ((Obj × Obj × Vector × Pull) → (Constraint × Pull)) - case object LinearLimits extends ((Constraint × Vector × Vector × Pull) → Pull) - case object AngularLimits extends ((Constraint × Vector × Vector × Pull) → Pull) - case object LinearSpring extends ((Constraint × Vector × Vector × Pull) → Pull) - case object AngularSpring extends ((Constraint × Vector × Vector × Pull) → Pull) - case object LinearMotor extends ((Constraint × Vector × Vector × Pull) → Pull) - case object AngularMotor extends ((Constraint × Vector × Vector × Pull) → Pull) + case object AddForce extends ((Obj.type × Vector.type × Vector.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Obj.type × Vector.type × Vector.type × Vector.type × Vector.type × Pull.type = ×(×(×(×(×(Obj, Vector), Vector), Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object GetVelocity extends (Obj.type → (Vector.type × Vector.type)) { + override def left: Obj.type = Obj + override def right: Vector.type × Vector.type = ×(Vector, Vector) + } + case object SetVelocity extends ((Obj.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Obj.type × Vector.type × Vector.type × Pull.type = ×(×(×(Obj, Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object SetLocked extends ((Obj.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Obj.type × Vector.type × Vector.type × Pull.type = ×(×(×(Obj, Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object SetMass extends ((Obj.type × Number.type × Pull.type) → Pull.type) { + override def left: Obj.type × Number.type × Pull.type = ×(×(Obj, Number), Pull) + override def right: Pull.type = Pull + } + case object SetFriction extends ((Obj.type × Number.type × Pull.type) → Pull.type) { + override def left: Obj.type × Number.type × Pull.type = ×(×(Obj, Number), Pull) + override def right: Pull.type = Pull + } + case object SetBounciness extends ((Obj.type × Number.type × Pull.type) → Pull.type) { + override def left: Obj.type × Number.type × Pull.type = ×(×(Obj, Number), Pull) + override def right: Pull.type = Pull + } + case object SetGravity extends ((Vector.type × Pull.type) → Pull.type) { + override def left: Vector.type × Pull.type = ×(Vector, Pull) + override def right: Pull.type = Pull + } + case object AddConstraint extends ((Obj.type × Obj.type × Vector.type × Pull.type) → (Constraint.type × Pull.type)) { + override def left: Obj.type × Obj.type × Vector.type × Pull.type = ×(×(×(Obj, Obj), Vector), Pull) + override def right: Constraint.type × Pull.type = ×(Constraint, Pull) + } + case object LinearLimits extends ((Constraint.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object AngularLimits extends ((Constraint.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object LinearSpring extends ((Constraint.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object AngularSpring extends ((Constraint.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object LinearMotor extends ((Constraint.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull) + override def right: Pull.type = Pull + } + case object AngularMotor extends ((Constraint.type × Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Vector.type × Vector.type × Pull.type = ×(×(×(Constraint, Vector), Vector), Pull) + override def right: Pull.type = Pull + } - case object If extends ((Bool × Pull × Pull × Pull) → Pull) - case object OnPlay extends ((Pull × Pull) → Pull) - case object LateUpdate extends ((Pull × Pull) → Pull) - case object BoxArt extends ((Pull × Pull) → Pull) - case class OnTouch(event: TouchEvent, finger: TouchFinger) extends ((Pull × Pull) → (Number × Number × Pull)) - case object OnSwipe extends ((Pull × Pull) → (Vector × Pull)) - case object OnCollision extends ((Obj × Pull × Pull) → (Obj × Number × Vector × Pull)) - case object Loop extends ((Number × Number × Pull × Pull) → (Number × Pull)) + case object If extends ((Bool.type × Pull.type × Pull.type × Pull.type) → Pull.type) { + override def left: Bool.type × Pull.type × Pull.type × Pull.type = ×(×(×(Bool, Pull), Pull), Pull) + override def right: Pull.type = Pull + } + case object OnPlay extends ((Pull.type × Pull.type) → Pull.type) { + override def left: Pull.type × Pull.type = ×(Pull, Pull) + override def right: Pull.type = Pull + } + case object LateUpdate extends ((Pull.type × Pull.type) → Pull.type) { + override def left: Pull.type × Pull.type = ×(Pull, Pull) + override def right: Pull.type = Pull + } + case object BoxArt extends ((Pull.type × Pull.type) → Pull.type) { + override def left: Pull.type × Pull.type = ×(Pull, Pull) + override def right: Pull.type = Pull + } + case class OnTouch(event: TouchEvent, finger: TouchFinger) extends ((Pull.type × Pull.type) → (Number.type × Number.type × Pull.type)) { + override def left: Pull.type × Pull.type = ×(Pull, Pull) + override def right: Number.type × Number.type × Pull.type = ×(×(Number, Number), Pull) + } + case object OnSwipe extends ((Pull.type × Pull.type) → (Vector.type × Pull.type)) { + override def left: Pull.type × Pull.type = ×(Pull, Pull) + override def right: Vector.type × Pull.type = ×(Vector, Pull) + } + case object OnCollision extends ((Obj.type × Pull.type × Pull.type) → (Obj.type × Number.type × Vector.type × Pull.type)) { + override def left: Obj.type × Pull.type × Pull.type = ×(×(Obj, Pull), Pull) + override def right: Obj.type × Number.type × Vector.type × Pull.type = ×(×(×(Obj, Number), Vector), Pull) + } + case object Loop extends ((Number.type × Number.type × Pull.type × Pull.type) → (Number.type × Pull.type)) { + override def left: Number.type × Number.type × Pull.type × Pull.type = ×(×(×(Number, Number), Pull), Pull) + override def right: Number.type × Pull.type = ×(Number, Pull) + } - case object Negate extends (Number → Number) - case object Inverse extends (Rotation → Rotation) - case object AddNumbers extends ((Number × Number) → Number) - case object AddVectors extends ((Vector × Vector) → Vector) - case object SubtractNumbers extends ((Number × Number) → Number) - case object SubtractVectors extends ((Vector × Vector) → Vector) - case object Multiply extends ((Number × Number) → Number) - case object Scale extends ((Vector × Number) → Vector) - case object Rotate extends ((Vector × Rotation) → Vector) - case object Combine extends ((Rotation × Rotation) → Rotation) - case object Divide extends ((Number × Number) → Number) - case object Power extends ((Number × Number) → Number) - case object EqualNumbers extends ((Number × Number) → Bool) - case object EqualVectors extends ((Vector × Vector) → Bool) - case object EqualObjects extends ((Obj × Obj) → Bool) - case object EqualTruths extends ((Bool × Bool) → Bool) - case object LessThan extends ((Number × Number) → Bool) - case object GreaterThan extends ((Number × Number) → Bool) - case object And extends ((Bool × Bool) → Bool) - case object Or extends ((Bool × Bool) → Bool) - case object Not extends (Bool → Bool) - case object Random extends ((Number × Number) → Number) - case object RandomSeed extends ((Number × Pull) → Pull) - case object Min extends ((Number × Number) → Number) - case object Max extends ((Number × Number) → Number) - case object Sin extends (Number → Number) - case object Cos extends (Number → Number) - case object Round extends (Number → Number) - case object Floor extends (Number → Number) - case object Ceiling extends (Number → Number) - case object Absolute extends (Number → Number) - case object Modulo extends ((Number × Number) → Number) - case object Logarithm extends ((Number × Number) → Number) - case object BreakVector extends (Vector → (Number × Number × Number)) - case object MakeVector extends ((Number × Number × Number) → Vector) - case object Normalize extends (Vector → Vector) - case object DotProduct extends ((Vector × Vector) → Vector) - case object CrossProduct extends ((Vector × Vector) → Vector) - case object BreakRotation extends (Rotation → (Number × Number × Number)) - case object MakeRotation extends ((Number × Number × Number) → Rotation) - case object Distance extends ((Vector × Vector) → Number) - case object LERP extends ((Rotation × Rotation × Number) → Rotation) - case object AxisAngle extends ((Vector × Number) → Rotation) - case object ScreenToWorld extends ((Number × Number) → (Vector × Vector)) - case object WorldToScreen extends (Vector → (Number × Number)) - case object LineVsPlane extends ((Vector × Vector × Vector × Vector) → Vector) - case object LookRotation extends ((Vector × Vector) → Rotation) + case object Negate extends (Number.type → Number.type) { + override def left: Number.type = Number + override def right: Number.type = Number + } + case object Inverse extends (Rotation.type → Rotation.type) { + override def left: Rotation.type = Rotation + override def right: Rotation.type = Rotation + } + case object AddNumbers extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object AddVectors extends ((Vector.type × Vector.type) → Vector.type) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Vector.type = Vector + } + case object SubtractNumbers extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object SubtractVectors extends ((Vector.type × Vector.type) → Vector.type) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Vector.type = Vector + } + case object Multiply extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object Scale extends ((Vector.type × Number.type) → Vector.type) { + override def left: Vector.type × Number.type = ×(Vector, Number) + override def right: Vector.type = Vector + } + case object Rotate extends ((Vector.type × Rotation.type) → Vector.type) { + override def left: Vector.type × Rotation.type = ×(Vector, Rotation) + override def right: Vector.type = Vector + } + case object Combine extends ((Rotation.type × Rotation.type) → Rotation.type) { + override def left: Rotation.type × Rotation.type = ×(Rotation, Rotation) + override def right: Rotation.type = Rotation + } + case object Divide extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object Power extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object EqualNumbers extends ((Number.type × Number.type) → Bool.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Bool.type = Bool + } + case object EqualVectors extends ((Vector.type × Vector.type) → Bool.type) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Bool.type = Bool + } + case object EqualObjects extends ((Obj.type × Obj.type) → Bool.type) { + override def left: Obj.type × Obj.type = ×(Obj, Obj) + override def right: Bool.type = Bool + } + case object EqualTruths extends ((Bool.type × Bool.type) → Bool.type) { + override def left: Bool.type × Bool.type = ×(Bool, Bool) + override def right: Bool.type = Bool + } + case object LessThan extends ((Number.type × Number.type) → Bool.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Bool.type = Bool + } + case object GreaterThan extends ((Number.type × Number.type) → Bool.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Bool.type = Bool + } + case object And extends ((Bool.type × Bool.type) → Bool.type) { + override def left: Bool.type × Bool.type = ×(Bool, Bool) + override def right: Bool.type = Bool + } + case object Or extends ((Bool.type × Bool.type) → Bool.type) { + override def left: Bool.type × Bool.type = ×(Bool, Bool) + override def right: Bool.type = Bool + } + case object Not extends (Bool.type → Bool.type) { + override def left: Bool.type = Bool + override def right: Bool.type = Bool + } + case object Random extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object RandomSeed extends ((Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Pull.type = ×(Number, Pull) + override def right: Pull.type = Pull + } + case object Min extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object Max extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object Sin extends (Number.type → Number.type) { + override def left: Number.type = Number + override def right: Number.type = Number + } + case object Cos extends (Number.type → Number.type) { + override def left: Number.type = Number + override def right: Number.type = Number + } + case object Round extends (Number.type → Number.type) { + override def left: Number.type = Number + override def right: Number.type = Number + } + case object Floor extends (Number.type → Number.type) { + override def left: Number.type = Number + override def right: Number.type = Number + } + case object Ceiling extends (Number.type → Number.type) { + override def left: Number.type = Number + override def right: Number.type = Number + } + case object Absolute extends (Number.type → Number.type) { + override def left: Number.type = Number + override def right: Number.type = Number + } + case object Modulo extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object Logarithm extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object BreakVector extends (Vector.type → (Number.type × Number.type × Number.type)) { + override def left: Vector.type = Vector + override def right: Number.type × Number.type × Number.type = ×(×(Number, Number), Number) + } + case object MakeVector extends ((Number.type × Number.type × Number.type) → Vector.type) { + override def left: Number.type × Number.type × Number.type = ×(×(Number, Number), Number) + override def right: Vector.type = Vector + } + case object Normalize extends (Vector.type → Vector.type) { + override def left: Vector.type = Vector + override def right: Vector.type = Vector + } + case object DotProduct extends ((Vector.type × Vector.type) → Vector.type) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Vector.type = Vector + } + case object CrossProduct extends ((Vector.type × Vector.type) → Vector.type) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Vector.type = Vector + } + case object BreakRotation extends (Rotation.type → (Number.type × Number.type × Number.type)) { + override def left: Rotation.type = Rotation + override def right: Number.type × Number.type × Number.type = ×(×(Number, Number), Number) + } + case object MakeRotation extends ((Number.type × Number.type × Number.type) → Rotation.type) { + override def left: Number.type × Number.type × Number.type = ×(×(Number, Number), Number) + override def right: Rotation.type = Rotation + } + case object Distance extends ((Vector.type × Vector.type) → Number.type) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Number.type = Number + } + case object LERP extends ((Rotation.type × Rotation.type × Number.type) → Rotation.type) { + override def left: Rotation.type × Rotation.type × Number.type = ×(×(Rotation, Rotation), Number) + override def right: Rotation.type = Rotation + } + case object AxisAngle extends ((Vector.type × Number.type) → Rotation.type) { + override def left: Vector.type × Number.type = ×(Vector, Number) + override def right: Rotation.type = Rotation + } + case object ScreenToWorld extends ((Number.type × Number.type) → (Vector.type × Vector.type)) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Vector.type × Vector.type = ×(Vector, Vector) + } + case object WorldToScreen extends (Vector.type → (Number.type × Number.type)) { + override def left: Vector.type = Vector + override def right: Number.type × Number.type = ×(Number, Number) + } + case object LineVsPlane extends ((Vector.type × Vector.type × Vector.type × Vector.type) → Vector.type) { + override def left: Vector.type × Vector.type × Vector.type × Vector.type = ×(×(×(Vector, Vector), Vector), Vector) + override def right: Vector.type = Vector + } + case object LookRotation extends ((Vector.type × Vector.type) → Rotation.type) { + override def left: Vector.type × Vector.type = ×(Vector, Vector) + override def right: Rotation.type = Rotation + } - case class GetNumber(name: String) extends (T → Number) - case class GetObject(name: String) extends (T → Obj) - case class GetVector(name: String) extends (T → Vector) - case class GetRotation(name: String) extends (T → Rotation) - case class GetTruth(name: String) extends (T → Bool) - case class GetConstraint(name: String) extends (T → Constraint) - case class SetNumber(name: String) extends ((Number × Pull) → Pull) - case class SetObject(name: String) extends ((Obj × Pull) → Pull) - case class SetVector(name: String) extends ((Vector × Pull) → Pull) - case class SetRotation(name: String) extends ((Rotation × Pull) → Pull) - case class SetTruth(name: String) extends ((Bool × Pull) → Pull) - case class SetConstraint(name: String) extends ((Constraint × Pull) → Pull) - case object SetNumberRef extends ((Number × Number × Pull) → Pull) - case object SetObjectRef extends ((Obj × Obj × Pull) → Pull) - case object SetVectorRef extends ((Vector × Vector × Pull) → Pull) - case object SetRotationRef extends ((Rotation × Rotation × Pull) → Pull) - case object SetTruthRef extends ((Bool × Bool × Pull) → Pull) - case object SetConstraintRef extends ((Constraint × Constraint × Pull) → Pull) - case object ListNumber extends ((Number × Number) → Number) - case object ListObject extends ((Obj × Number) → Obj) - case object ListVector extends ((Vector × Number) → Vector) - case object ListRotation extends ((Rotation × Number) → Rotation) - case object ListTruth extends ((Bool × Number) → Bool) - case object ListConstraint extends ((Constraint × Number) → Constraint) - case object Increment extends ((Number × Pull) → Pull) - case object Decrement extends ((Number × Pull) → Pull) + case class GetNumber(name: String) extends (T.type → Number.type) { + override def left: T.type = T + override def right: Number.type = Number + } + case class GetObject(name: String) extends (T.type → Obj.type) { + override def left: T.type = T + override def right: Obj.type = Obj + } + case class GetVector(name: String) extends (T.type → Vector.type) { + override def left: T.type = T + override def right: Vector.type = Vector + } + case class GetRotation(name: String) extends (T.type → Rotation.type) { + override def left: T.type = T + override def right: Rotation.type = Rotation + } + case class GetTruth(name: String) extends (T.type → Bool.type) { + override def left: T.type = T + override def right: Bool.type = Bool + } + case class GetConstraint(name: String) extends (T.type → Constraint.type) { + override def left: T.type = T + override def right: Constraint.type = Constraint + } + case class SetNumber(name: String) extends ((Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Pull.type = ×(Number, Pull) + override def right: Pull.type = Pull + } + case class SetObject(name: String) extends ((Obj.type × Pull.type) → Pull.type) { + override def left: Obj.type × Pull.type = ×(Obj, Pull) + override def right: Pull.type = Pull + } + case class SetVector(name: String) extends ((Vector.type × Pull.type) → Pull.type) { + override def left: Vector.type × Pull.type = ×(Vector, Pull) + override def right: Pull.type = Pull + } + case class SetRotation(name: String) extends ((Rotation.type × Pull.type) → Pull.type) { + override def left: Rotation.type × Pull.type = ×(Rotation, Pull) + override def right: Pull.type = Pull + } + case class SetTruth(name: String) extends ((Bool.type × Pull.type) → Pull.type) { + override def left: Bool.type × Pull.type = ×(Bool, Pull) + override def right: Pull.type = Pull + } + case class SetConstraint(name: String) extends ((Constraint.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Pull.type = ×(Constraint, Pull) + override def right: Pull.type = Pull + } + case object SetNumberRef extends ((Number.type × Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Number.type × Pull.type = ×(×(Number, Number), Pull) + override def right: Pull.type = Pull + } + case object SetObjectRef extends ((Obj.type × Obj.type × Pull.type) → Pull.type) { + override def left: Obj.type × Obj.type × Pull.type = ×(×(Obj, Obj), Pull) + override def right: Pull.type = Pull + } + case object SetVectorRef extends ((Vector.type × Vector.type × Pull.type) → Pull.type) { + override def left: Vector.type × Vector.type × Pull.type = ×(×(Vector, Vector), Pull) + override def right: Pull.type = Pull + } + case object SetRotationRef extends ((Rotation.type × Rotation.type × Pull.type) → Pull.type) { + override def left: Rotation.type × Rotation.type × Pull.type = ×(×(Rotation, Rotation), Pull) + override def right: Pull.type = Pull + } + case object SetTruthRef extends ((Bool.type × Bool.type × Pull.type) → Pull.type) { + override def left: Bool.type × Bool.type × Pull.type = ×(×(Bool, Bool), Pull) + override def right: Pull.type = Pull + } + case object SetConstraintRef extends ((Constraint.type × Constraint.type × Pull.type) → Pull.type) { + override def left: Constraint.type × Constraint.type × Pull.type = ×(×(Constraint, Constraint), Pull) + override def right: Pull.type = Pull + } + case object ListNumber extends ((Number.type × Number.type) → Number.type) { + override def left: Number.type × Number.type = ×(Number, Number) + override def right: Number.type = Number + } + case object ListObject extends ((Obj.type × Number.type) → Obj.type) { + override def left: Obj.type × Number.type = ×(Obj, Number) + override def right: Obj.type = Obj + } + case object ListVector extends ((Vector.type × Number.type) → Vector.type) { + override def left: Vector.type × Number.type = ×(Vector, Number) + override def right: Vector.type = Vector + } + case object ListRotation extends ((Rotation.type × Number.type) → Rotation.type) { + override def left: Rotation.type × Number.type = ×(Rotation, Number) + override def right: Rotation.type = Rotation + } + case object ListTruth extends ((Bool.type × Number.type) → Bool.type) { + override def left: Bool.type × Number.type = ×(Bool, Number) + override def right: Bool.type = Bool + } + case object ListConstraint extends ((Constraint.type × Number.type) → Constraint.type) { + override def left: Constraint.type × Number.type = ×(Constraint, Number) + override def right: Constraint.type = Constraint + } + case object Increment extends ((Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Pull.type = ×(Number, Pull) + override def right: Pull.type = Pull + } + case object Decrement extends ((Number.type × Pull.type) → Pull.type) { + override def left: Number.type × Pull.type = ×(Number, Pull) + override def right: Pull.type = Pull + } } - implicit lazy val fanscript: Cartesian[Pin, →, T, ×] with ArrowLoop[Pin, →, T, ×, →] = new Cartesian[Pin, →, T, ×] with ArrowLoop[Pin, →, T, ×, →] { + implicit lazy val fanscript: + Cartesian[Pin, PinEv, →, T.type, ×] with ArrowLoop[Pin, PinEv, →, T.type, ×, →] = + new Cartesian[Pin, PinEv, →, T.type, ×] with ArrowLoop[Pin, PinEv, →, T.type, ×, →] { - override def id[A <: Pin]: A → A = - Id[A]() + override def duplicate[A <: Pin](implicit a: PinEv[A]): A → (A × A) = + Duplicate(a.value) - override def duplicate[A <: Pin]: A → (A × A) = - Duplicate[A]() + override def terminate[A <: Pin](implicit a: PinEv[A]): A → T.type = + Terminate(a.value) - override def terminate[A <: Pin]: A → T = - Terminate[A]() + override def loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)): A → B = + Loop(f) - override def swap[A <: Pin, B <: Pin]: (A × B) → (B × A) = - Swap() + override def lift[A <: Pin, B <: Pin](f: A → B): A → B = + f - override def lift[A <: Pin, B <: Pin](f: A → B): A → B = - f + override def id[A <: Pin](implicit a: PinEv[A]): A → A = + Id(a.value) - override def strongProfunctorCategory: Monoidal[Pin, →, T, ×] = this + override def strongProfunctorCategory: Monoidal[Pin, PinEv, →, T.type, ×] = + this - override def first[A <: Pin, B <: Pin, C <: Pin]: (A → B) ⇒ ((A × C) → (B × C)) = - Bimap[A, B, C, C](_, id[C]) + override def first[A <: Pin, B <: Pin, C <: Pin](f: A → B)(implicit c: PinEv[C]): (A × C) → (B × C) = + bimap(f, id[C]) - override def second[A <: Pin, B <: Pin, C <: Pin]: (A → B) ⇒ ((C × A) → (C × B)) = - (f: A → B) => { - val firstf: (A × C) → (B × C) = first[A, B, C](f) - AndThen(Swap(), AndThen(firstf, Swap())) + override def second[A <: Pin, B <: Pin, C <: Pin](f: A → B)(implicit c: PinEv[C]): (C × A) → (C × B) = { + implicit val a: PinEv[A] = f.leftEv + implicit val b: PinEv[B] = f.rightEv + val unswapped: (A × C) → (B × C) = first(f) + andThen(swap[C, A], andThen(unswapped, swap[B, C])) } - override def loop[A <: Pin, B <: Pin, C <: Pin](f: (A × C) → (B × C)): A → B = - Loop(f) + override def profunctorLeftConstraint[A <: Pin, B <: Pin](f: A → B): PinEv[A] = + f.leftEv - override def associateRight[A <: Pin, B <: Pin, C <: Pin]: ((A × B) × C) → (A × (B × C)) = - Associate[A, B, C]() + override def profunctorRightConstraint[A <: Pin, B <: Pin](f: A → B): PinEv[B] = + f.rightEv - override def unitorLeft[A <: Pin]: (T × A) → A = - Unit() + override def swap[A <: Pin, B <: Pin](implicit a: PinEv[A], b: PinEv[B]): (A × B) → (B × A) = + Swap(a.value, b.value) - override def deunitorLeft[A <: Pin]: A → (T × A) = - Deunit() + override implicit def unitConstraint: PinEv[T.type] = + PinEv.pinValueForT - override def compose[A <: Pin, B <: Pin, C <: Pin](f: B → C, g: A → B): A → C = - AndThen(g, f) + override def associateRight[A <: Pin, B <: Pin, C <: Pin](implicit a: PinEv[A], b: PinEv[B], c: PinEv[C]): ((A × B) × C) → (A × (B × C)) = + Associate(a.value, b.value, c.value) - override def andThen[A <: Pin, B <: Pin, C <: Pin](f: A → B, g: B → C): A → C = - AndThen(f, g) + override def unitorLeft[A <: Pin](implicit a: PinEv[A]): (T.type × A) → A = + Unit(a.value) - override def bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A → C, g: B → D): (A × B) → (C × D) = - Bimap(f, g) + override def deunitorLeft[A <: Pin](implicit a: PinEv[A]): A → (T.type × A) = + Deunit(a.value) - } + override def homLeftConstraint[A <: Pin, B <: Pin](hom: A → B): PinEv[A] = + hom.leftEv + + override def homRightConstraint[A <: Pin, B <: Pin](hom: A → B): PinEv[B] = + hom.rightEv + + override def andThen[A <: Pin, B <: Pin, C <: Pin](f: A → B, g: B → C): A → C = + AndThen(f, g) + + override def compose[A <: Pin, B <: Pin, C <: Pin](f: B → C, g: A → B): A → C = + andThen(g, f) + + override implicit def bifunctorApplyConstraint[A <: Pin, B <: Pin](implicit a: PinEv[A], b: PinEv[B]): PinEv[A × B] = + PinEv.pinValueForProduct[A, B](a, b) + + override def bifunctorLeftConstraint[A <: Pin, B <: Pin](implicit e: PinEv[A × B]): PinEv[A] = + new PinEv[A] { + override val value: A = e.value.a + } + + override def bifunctorRightConstraint[A <: Pin, B <: Pin](implicit e: PinEv[A × B]): PinEv[B] = + new PinEv[B] { + override val value: B = e.value.b + } + + override def bimap[A <: Pin, B <: Pin, C <: Pin, D <: Pin](f: A → C, g: B → D): (A × B) → (C × D) = + Bimap(f, g) + + } } diff --git a/core/src/main/scala/tf/bug/fancade/Main.scala b/core/src/main/scala/tf/bug/fancade/Main.scala index 9edf143..385661b 100644 --- a/core/src/main/scala/tf/bug/fancade/Main.scala +++ b/core/src/main/scala/tf/bug/fancade/Main.scala @@ -6,145 +6,145 @@ object Main { import Fanscript._ import tf.bug.shinji.syntax.all._ // min, max, start, result, after -> end, index, sum, before - val sum: (Number × Number × Pull × Number × Pull) → (Pull × Number × Number × Pull) = { - val getSum: T → Number = Builtin.GetNumber("Sum") - val setSum: (Number × Pull) → Pull = Builtin.SetNumber("Sum") - val addToSum: (Number × Pull) → Pull = { - val add: (Number × Number) → Number = Builtin.AddNumbers - val sumAsFirstInput: (T × Number) → (Number × Number) = getSum.first[Number] - val branch: Number → (T × Number) = deunitL(fanscript) - val justSecondInput: Number → (Number × Number) = branch >>> sumAsFirstInput - val addSum: Number → Number = add.ldimap(justSecondInput) - val storeSum: (Number × Pull) → Pull = setSum - storeSum.ldimap(fanscript.lbimap(addSum)) + val sum: (Number.type × Number.type × Pull.type × Number.type × Pull.type) → (Pull.type × Number.type × Number.type × Pull.type) = { + val getSum: T.type → Number.type = Builtin.GetNumber("Sum") + val setSum: (Number.type × Pull.type) → Pull.type = Builtin.SetNumber("Sum") + val addToSum: (Number.type × Pull.type) → Pull.type = { + val add: (Number.type × Number.type) → Number.type = Builtin.AddNumbers + val sumAsFirstInput: (T.type × Number.type) → (Number.type × Number.type) = fanscript.first(getSum) + val branch: Number.type → (T.type × Number.type) = fanscript.deunitorLeft + val justSecondInput: Number.type → (Number.type × Number.type) = fanscript.andThen(branch, sumAsFirstInput) + val addSum: Number.type → Number.type = fanscript.ldimap[Number.type × Number.type, Number.type, Number.type](justSecondInput).apply(add) + val storeSum: (Number.type × Pull.type) → Pull.type = setSum + fanscript.ldimap[Number.type × Pull.type, Pull.type, Number.type × Pull.type](fanscript.lbimap(addSum)).apply(storeSum) } - val getIndex: T → Number = Builtin.GetNumber("Index") - val setIndex: (Number × Pull) → Pull = Builtin.SetNumber("Index") - val indexGreaterThan: Number → Bool = { - val greaterThan: (Number × Number) → Bool = Builtin.GreaterThan - val indexAsFirstInput: (T × Number) → (Number × Number) = getIndex.first[Number] - val branch: Number → (T × Number) = deunitL(fanscript) - val comparisonAsSecondInput: Number → (Number × Number) = branch >>> indexAsFirstInput - comparisonAsSecondInput >>> greaterThan + val getIndex: T.type → Number.type = Builtin.GetNumber("Index") + val setIndex: (Number.type × Pull.type) → Pull.type = Builtin.SetNumber("Index") + val indexGreaterThan: Number.type → Bool.type = { + val greaterThan: (Number.type × Number.type) → Bool.type = Builtin.GreaterThan + val indexAsFirstInput: (T.type × Number.type) → (Number.type × Number.type) = fanscript.first(getIndex) + val branch: Number.type → (T.type × Number.type) = fanscript.deunitorLeft + val comparisonAsSecondInput: Number.type → (Number.type × Number.type) = fanscript.andThen(branch, indexAsFirstInput) + fanscript.andThen(comparisonAsSecondInput, greaterThan) } - val indexNotGreaterThan: Number → Bool = indexGreaterThan >>> Builtin.Not - val checkContinue: (Number × Pull × Pull × Pull) → Pull = { - val ifBlock: (Bool × Pull × Pull × Pull) → Pull = Builtin.If - val checkGreater: (Number × Pull × Pull × Pull) → (Bool × Pull × Pull × Pull) = { - val one: (Number × Pull) → (Bool × Pull) = indexGreaterThan.first[Pull] - val two: (Number × Pull × Pull) → (Bool × Pull × Pull) = fanscript.first(one) - val three: (Number × Pull × Pull × Pull) → (Bool × Pull × Pull × Pull) = fanscript.first(two) + val indexNotGreaterThan: Number.type → Bool.type = fanscript.andThen(indexGreaterThan, Builtin.Not) + val checkContinue: (Number.type × Pull.type × Pull.type × Pull.type) → Pull.type = { + val ifBlock: (Bool.type × Pull.type × Pull.type × Pull.type) → Pull.type = Builtin.If + val checkGreater: (Number.type × Pull.type × Pull.type × Pull.type) → (Bool.type × Pull.type × Pull.type × Pull.type) = { + val one: (Number.type × Pull.type) → (Bool.type × Pull.type) = fanscript.first(indexGreaterThan) + val two: (Number.type × Pull.type × Pull.type) → (Bool.type × Pull.type × Pull.type) = fanscript.first(one) + val three: (Number.type × Pull.type × Pull.type × Pull.type) → (Bool.type × Pull.type × Pull.type × Pull.type) = fanscript.first(two) three } fanscript.andThen(checkGreater, ifBlock) } // sumToIndex -> before - val initializeSum: Pull → Pull = { - val zero: T → Number = Builtin.NumberValue(0.0F) - val zeroAsInput: (T × Pull) → (Number × Pull) = zero.first[Pull] - val branch: Pull → (T × Pull) = fanscript.deunitorLeft[Pull] - branch >>> zeroAsInput >>> setSum + val initializeSum: Pull.type → Pull.type = { + val zero: T.type → Number.type = Builtin.NumberValue(0.0F) + val zeroAsInput: (T.type × Pull.type) → (Number.type × Pull.type) = fanscript.first(zero) + val branch: Pull.type → (T.type × Pull.type) = fanscript.deunitorLeft[Pull.type] + fanscript.andThen(fanscript.andThen(branch, zeroAsInput), setSum) } // min, indexToLoopStart -> sumToIndex - val initializeIndex: (Number × Pull) → Pull = setIndex + val initializeIndex: (Number.type × Pull.type) → Pull.type = setIndex // max, start, ◌, after -> (indexToLoopStart + incrementToLoop) - val startLoop: (Number × Pull × Pull × Pull) → Pull = checkContinue + val startLoop: (Number.type × Pull.type × Pull.type × Pull.type) → Pull.type = checkContinue // result, increaseSum -> end - val increaseSum: (Number × Pull) → Pull = addToSum + val increaseSum: (Number.type × Pull.type) → Pull.type = addToSum // incrementToLoop -> increaseSum - val incrementIndex: Pull → Pull = { - val get: T → Number = getIndex - val set: (Number × Pull) → Pull = setIndex - val one: T → Number = Builtin.NumberValue(1.0F) - val additionOperands: T → (Number × Number) = get &&& one - val add: T → Number = additionOperands >>> Builtin.AddNumbers - val carryPull: (T × Pull) → (Number × Pull) = add.first[Pull] - val branch: Pull → (T × Pull) = fanscript.deunitorLeft[Pull] - branch >>> carryPull >>> set + val incrementIndex: Pull.type → Pull.type = { + val get: T.type → Number.type = getIndex + val set: (Number.type × Pull.type) → Pull.type = setIndex + val one: T.type → Number.type = Builtin.NumberValue(1.0F) + val additionOperands: T.type → (Number.type × Number.type) = fanscript.merge(get, one) + val add: T.type → Number.type = fanscript.andThen(additionOperands, Builtin.AddNumbers) + val carryPull: (T.type × Pull.type) → (Number.type × Pull.type) = fanscript.first(add) + val branch: Pull.type → (T.type × Pull.type) = fanscript.deunitorLeft[Pull.type] + fanscript.andThen(fanscript.andThen(branch, carryPull), set) } // min, indexToLoopStart -> before - val initialize: (Number × Pull) → Pull = initializeIndex >>> initializeSum + val initialize: (Number.type × Pull.type) → Pull.type = fanscript.andThen(initializeIndex, initializeSum) // result, incrementToLoop -> end - val postLoop: (Number × Pull) → Pull = { - val carryResult = fanscript.second[Pull, Pull, Number](incrementIndex) + val postLoop: (Number.type × Pull.type) → Pull.type = { + val carryResult = fanscript.second[Pull.type, Pull.type, Number.type](incrementIndex) fanscript.andThen(carryResult, increaseSum) } // max, start, after -> (indexToLoopStart + incrementToLoop) - val condition: (Number × Pull × Pull) → Pull = { - val zThree: (Number × Pull) → (Number × Pull × Pull) = + val condition: (Number.type × Pull.type × Pull.type) → Pull.type = { + val zThree: (Number.type × Pull.type) → (Number.type × Pull.type × Pull.type) = fanscript.andThen(fanscript.deunitorRight, fanscript.rbimap(Z)) - val zFour: (Number × Pull × Pull) → (Number × Pull × Pull × Pull) = + val zFour: (Number.type × Pull.type × Pull.type) → (Number.type × Pull.type × Pull.type × Pull.type) = fanscript.lbimap(zThree) - fanscript.ldimap(zFour)(checkContinue) + fanscript.ldimap[Number.type × Pull.type × Pull.type × Pull.type, Pull.type, Number.type × Pull.type × Pull.type](zFour).apply(checkContinue) } // min, max, start, result, after -> end, index, sum, before - val result: (Number × Number × Pull × Number × Pull) → (Pull × Number × Number × Pull) = { + val result: (Number.type × Number.type × Pull.type × Number.type × Pull.type) → (Pull.type × Number.type × Number.type × Pull.type) = { // max, start, after -> indexToLoopStart, incrementToLoop - val duplicateCondition: (Number × Pull × Pull) → (Pull × Pull) = + val duplicateCondition: (Number.type × Pull.type × Pull.type) → (Pull.type × Pull.type) = fanscript.andThen(condition, fanscript.duplicate) // min, indexToLoopStart, result, incrementToLoop -> before, end - val conditionPrecursors: (Number × Pull × Number × Pull) → (Pull × Pull) = - fanscript.andThen(fanscript.associateRight[Number × Pull, Number, Pull], fanscript.split[Number × Pull, Pull, Number × Pull, Pull](initialize, postLoop)) + val conditionPrecursors: (Number.type × Pull.type × Number.type × Pull.type) → (Pull.type × Pull.type) = + fanscript.associateRight[Number.type × Pull.type, Number.type, Pull.type] >>> (initialize *** postLoop) // min, result, (indexToLoopStart, incrementToLoop) -> end, before - val orientConditionPrecursors: ((Number × Number) × (Pull × Pull)) → (Pull × Pull) = { - val flattenAssoc: ((Number × Number) × (Pull × Pull)) → (((Number × Number) × Pull) × Pull) = fanscript.associateLeft - val assocInside: (((Number × Number) × Pull) × Pull) → ((Number × (Number × Pull)) × Pull) = fanscript.lbimap(fanscript.associateRight) - val swapInside: ((Number × (Number × Pull)) × Pull) → ((Number × (Pull × Number)) × Pull) = fanscript.lbimap(fanscript.rbimap(fanscript.swap)) - val reassocInside: ((Number × (Pull × Number)) × Pull) → (((Number × Pull) × Number) × Pull) = fanscript.lbimap(fanscript.associateLeft) - val orientConditionInputs: ((Number × Number) × (Pull × Pull)) → (((Number × Pull) × Number) × Pull) = + val orientConditionPrecursors: ((Number.type × Number.type) × (Pull.type × Pull.type)) → (Pull.type × Pull.type) = { + val flattenAssoc: ((Number.type × Number.type) × (Pull.type × Pull.type)) → (((Number.type × Number.type) × Pull.type) × Pull.type) = fanscript.associateLeft + val assocInside: (((Number.type × Number.type) × Pull.type) × Pull.type) → ((Number.type × (Number.type × Pull.type)) × Pull.type) = fanscript.lbimap(fanscript.associateRight) + val swapInside: ((Number.type × (Number.type × Pull.type)) × Pull.type) → ((Number.type × (Pull.type × Number.type)) × Pull.type) = fanscript.lbimap(fanscript.rbimap(fanscript.swap)) + val reassocInside: ((Number.type × (Pull.type × Number.type)) × Pull.type) → (((Number.type × Pull.type) × Number.type) × Pull.type) = fanscript.lbimap(fanscript.associateLeft) + val orientConditionInputs: ((Number.type × Number.type) × (Pull.type × Pull.type)) → (((Number.type × Pull.type) × Number.type) × Pull.type) = fanscript.andThen(fanscript.andThen(fanscript.andThen(flattenAssoc, assocInside), swapInside), reassocInside) - val swapEnd: (Pull × Pull) → (Pull × Pull) = fanscript.swap + val swapEnd: (Pull.type × Pull.type) → (Pull.type × Pull.type) = fanscript.swap fanscript.dimap(orientConditionInputs, swapEnd)(conditionPrecursors) } // min, max, start, result, after -> end, before - val nonNumbers: (Number × Number × Pull × Number × Pull) → (Pull × Pull) = { - val duplicateConditionLeftNumbers: ((Number × Number) × (Number × Pull × Pull)) → ((Number × Number) × (Pull × Pull)) = - fanscript.second[Number × Pull × Pull, Pull × Pull, Number × Number](duplicateCondition) + val nonNumbers: (Number.type × Number.type × Pull.type × Number.type × Pull.type) → (Pull.type × Pull.type) = { + val duplicateConditionLeftNumbers: ((Number.type × Number.type) × (Number.type × Pull.type × Pull.type)) → ((Number.type × Number.type) × (Pull.type × Pull.type)) = + fanscript.second[Number.type × Pull.type × Pull.type, Pull.type × Pull.type, Number.type × Number.type](duplicateCondition) // (min, result), (max, start, after) -> end, before - val aggregate: ((Number × Number) × (Number × Pull × Pull)) → (Pull × Pull) = + val aggregate: ((Number.type × Number.type) × (Number.type × Pull.type × Pull.type)) → (Pull.type × Pull.type) = fanscript.andThen(duplicateConditionLeftNumbers, orientConditionPrecursors) // (max, start, after, (min, result)) -> end, before - val align: (Number × Pull × Pull × (Number × Number)) → (Pull × Pull) = + val align: (Number.type × Pull.type × Pull.type × (Number.type × Number.type)) → (Pull.type × Pull.type) = fanscript.andThen(fanscript.swap, aggregate) // max, start, after, min, result -> end, before - val assoc: (Number × Pull × Pull × Number × Number) → (Pull × Pull) = + val assoc: (Number.type × Pull.type × Pull.type × Number.type × Number.type) → (Pull.type × Pull.type) = fanscript.andThen(fanscript.associateRight, align) // min, max, start, result, after -> max, start, after, min, result - val realign: ((((Number × Number) × Pull) × Number) × Pull) → ((((Number × Pull) × Pull) × Number) × Number) = { - val one: ((((Number × Number) × Pull) × Number) × Pull) → (((Number × (Number × Pull)) × Number) × Pull) = + val realign: ((((Number.type × Number.type) × Pull.type) × Number.type) × Pull.type) → ((((Number.type × Pull.type) × Pull.type) × Number.type) × Number.type) = { + val one: ((((Number.type × Number.type) × Pull.type) × Number.type) × Pull.type) → (((Number.type × (Number.type × Pull.type)) × Number.type) × Pull.type) = fanscript.lbimap(fanscript.lbimap(fanscript.associateRight)) - val two: (((Number × (Number × Pull)) × Number) × Pull) → ((((Number × Pull) × Number) × Number) × Pull) = + val two: (((Number.type × (Number.type × Pull.type)) × Number.type) × Pull.type) → ((((Number.type × Pull.type) × Number.type) × Number.type) × Pull.type) = fanscript.lbimap(fanscript.lbimap(fanscript.swap)) - val three: ((((Number × Pull) × Number) × Number) × Pull) → (((Number × Pull) × Number) × (Number × Pull)) = + val three: ((((Number.type × Pull.type) × Number.type) × Number.type) × Pull.type) → (((Number.type × Pull.type) × Number.type) × (Number.type × Pull.type)) = fanscript.associateRight - val four: (((Number × Pull) × Number) × (Number × Pull)) → (((Number × Pull) × Number) × (Pull × Number)) = + val four: (((Number.type × Pull.type) × Number.type) × (Number.type × Pull.type)) → (((Number.type × Pull.type) × Number.type) × (Pull.type × Number.type)) = fanscript.rbimap(fanscript.swap) - val five: (((Number × Pull) × Number) × (Pull × Number)) → ((((Number × Pull) × Number) × Pull) × Number) = + val five: (((Number.type × Pull.type) × Number.type) × (Pull.type × Number.type)) → ((((Number.type × Pull.type) × Number.type) × Pull.type) × Number.type) = fanscript.associateLeft - val six: ((((Number × Pull) × Number) × Pull) × Number) → (((Number × Pull) × (Number × Pull)) × Number) = + val six: ((((Number.type × Pull.type) × Number.type) × Pull.type) × Number.type) → (((Number.type × Pull.type) × (Number.type × Pull.type)) × Number.type) = fanscript.lbimap(fanscript.associateRight) - val seven: (((Number × Pull) × (Number × Pull)) × Number) → (((Number × Pull) × (Pull × Number)) × Number) = + val seven: (((Number.type × Pull.type) × (Number.type × Pull.type)) × Number.type) → (((Number.type × Pull.type) × (Pull.type × Number.type)) × Number.type) = fanscript.lbimap(fanscript.rbimap(fanscript.swap)) - val eight: (((Number × Pull) × (Pull × Number)) × Number) → ((((Number × Pull) × Pull) × Number) × Number) = + val eight: (((Number.type × Pull.type) × (Pull.type × Number.type)) × Number.type) → ((((Number.type × Pull.type) × Pull.type) × Number.type) × Number.type) = fanscript.lbimap(fanscript.associateLeft) fanscript.andThen( @@ -175,10 +175,10 @@ object Main { } // end, before -> end, index, sum, before - val addOutputs: (Pull × Pull) → (Pull × Number × Number × Pull) = + val addOutputs: (Pull.type × Pull.type) → (Pull.type × Number.type × Number.type × Pull.type) = fanscript.lbimap(fanscript.andThen( - fanscript.andThen[Pull, Pull × T, Pull × Number](fanscript.deunitorRight[Pull], fanscript.rbimap(getIndex)), - fanscript.andThen[Pull × Number, Pull × Number × T, Pull × Number × Number](fanscript.deunitorRight[Pull × Number], fanscript.rbimap(getSum)) + fanscript.andThen[Pull.type, Pull.type × T.type, Pull.type × Number.type](fanscript.deunitorRight[Pull.type], fanscript.rbimap(getIndex)), + fanscript.andThen[Pull.type × Number.type, Pull.type × Number.type × T.type, Pull.type × Number.type × Number.type](fanscript.deunitorRight[Pull.type × Number.type], fanscript.rbimap(getSum)) )) fanscript.andThen(nonNumbers, addOutputs)