Created
October 6, 2017 08:34
-
-
Save bkase/16b2de2c3bcae1b89287f402daea86ba to your computer and use it in GitHub Desktop.
Rough Sketch Functional Animations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SUPER ROUGH ideas about distributive property on Animations | |
// This is the "current relative time as input" rather than the "0 to 1 as input" (unit) version of the animation | |
// this has flaws, but simple to show (or not) the distributive property of sequence and parallel | |
infix operator <>: AdditionPrecedence | |
protocol Semigroup { | |
static func <>(lhs: Self, rhs: Self) -> Self | |
} | |
indirect enum FreeSemigroup<A>: Semigroup { | |
case One(A) | |
case More(A, FreeSemigroup<A>) | |
} | |
// The seq/paralell forms an identity-less tropical-like semiring ( https://github.com/paf31/purescript-tropical/blob/master/src/Data/Semiring/Tropical.purs ) | |
// over the durations (so distributive property holds there) | |
// Let A, B, C be animations | |
// Want to show: A * (B + C) | |
// Starting from: A * B + A * C | |
// A : B + A : C <-- (by definition of * (the colon just means ternary it)) | |
// A : B <> A : C <-- (by definition of +; pointwise a semigroup) | |
// (A <> A) : (B <> C) <-- (I think <> distributes over the ternary, but I might be too tired) | |
// A : (B <> C) <-- this step is where it breaks down, but it makes intuitive sense just thinking about animations in the abstract: | |
// Running an animation in parallel with itself should no-op... Not sure what the impl would need to be for parallel, | |
// but I think this is the problem. | |
// A : (B + C) <-- by definition of + | |
// A * (B + C) <-- by definition of * | |
// qed | |
struct Animation<A: Semigroup> { | |
let duration: Double | |
let run: (Double) -> A | |
static func * (lhs: Animation, rhs: Animation) -> Animation { | |
return Animation(duration: lhs.duration + rhs.duration) { t in | |
(t < lhs.duration) ? lhs.run(t) : rhs.run(t) | |
} | |
} | |
// Animation<FreeSemigroup<A>> recovers the power of the tupling of the sequence | |
// (mostly sort of). I think the semigroup constraint is more powerful than the tupling. | |
static func + (lhs: Animation, rhs: Animation) -> Animation { | |
return Animation(duration: max(lhs.duration, rhs.duration)) { t in | |
lhs.run(t) <> rhs.run(t) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment