Last active
February 27, 2021 14:53
-
-
Save chrisfarber/b4b0eddca2bb54bf36f7babeb1cfa8a1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
import Foundation | |
import RxSwift | |
class Ref<E> { | |
private let value : Variable<E> | |
private let q = dispatch_queue_create("net.chrisfarber.Ref<\(E.self)>", DISPATCH_QUEUE_SERIAL) | |
init(i:E) { | |
value = Variable(i) | |
} | |
func change(f: E -> E) -> E { | |
var v: E! = nil | |
let container = value | |
dispatch_sync(q) { | |
v = container.value | |
v = f(v) | |
container.value = v | |
} | |
return v | |
} | |
func change(f: (inout E) -> Void -> Void) -> E { | |
var v: E! = nil | |
dispatch_sync(q) { | |
v = self.value.value | |
f(&v!)() | |
self.value.value = v! | |
} | |
return v | |
} | |
func observe<G>(f: (E) -> G) -> Observable<G> { | |
return value.asObservable().map(f) | |
} | |
func observe<G>(f: E -> Void -> G) -> Observable<G> { | |
return observe(lift(f)) | |
} | |
func current() -> E { | |
return value.value | |
} | |
func current<G>(prop: (E) -> (G)) -> G { | |
return prop(value.value) | |
} | |
func current<G>(prop: E -> Void -> G) -> G { | |
return prop(value.value)() | |
} | |
func values() -> Observable<E> { | |
return value.asObservable() | |
} | |
} | |
infix operator =>| { associativity left precedence 140 } | |
func =>| <E, G> (mutation: (G) -> ((E) -> E), ref: Ref<E>) -> (G) -> Void { | |
return { val in | |
ref.change(mutation(val)) | |
} | |
} | |
postfix operator ^ {} | |
postfix func ^ <E> (mut: (inout E) -> Void -> Void) -> E -> E { | |
return { e in | |
var e = e | |
mut(&e)() | |
return e | |
} | |
} | |
postfix func ^ <E,A> (mut: (inout E) -> A -> Void) -> A -> E -> E { | |
return { a in | |
return { e in | |
var e = e | |
mut(&e)(a) | |
return e | |
} | |
} | |
} | |
infix operator <+ { precedence 160 } | |
func <+ <E,A,R> (proj: E -> A -> R, a: A) -> E -> R { | |
return lift(proj, a) | |
} | |
func <+ <E,A> (mut: (inout E) -> A -> Void, a: A) -> E -> E { | |
return lift(mut, a) | |
} | |
func <+ <E,A,B> (mut: (inout E) -> (A, B) -> Void, stuff: (A, B)) -> E -> E { | |
return lift(mut, stuff.0, stuff.1) | |
} | |
func <+ <E,A,B,C> (mut: (inout E) -> (A, B, C) -> Void, stuff: (A, B, C)) -> E -> E { | |
return lift(mut, stuff.0, stuff.1, stuff.2) | |
} | |
func lift<E>(mut: (inout E) -> Void -> Void) -> E -> E { | |
return { v in | |
var v = v | |
mut(&v)() | |
return v | |
} | |
} | |
func lift<E,A>(mut: ((inout E) -> A -> Void), _ a: A) -> E -> E { | |
return { v in | |
var v = v | |
mut(&v)(a) | |
return v | |
} | |
} | |
func lift<E,A,B>(mut: ((inout E) -> (A, B) -> Void), _ a: A, _ b: B) -> E -> E { | |
return { v in | |
var v = v | |
mut(&v)(a,b) | |
return v | |
} | |
} | |
func lift<E,A,B,C>(mut: ((inout E) -> (A, B, C) -> Void), _ a: A, _ b: B, _ c: C) -> E -> E { | |
return { v in | |
var v = v | |
mut(&v)(a,b,c) | |
return v | |
} | |
} | |
func lift<E,R>(proj: E -> () -> R) -> E -> R { | |
return { e in | |
return proj(e)() | |
} | |
} | |
func lift<E,A,R>(proj: E -> A -> R, _ a: A) -> E -> R { | |
return { e in | |
return proj(e)(a) | |
} | |
} | |
func lift<E,A,B,R>(proj: E -> (A, B) -> R, _ a: A, _ b: B) -> E -> R { | |
return { e in | |
return proj(e)(a,b) | |
} | |
} | |
func lift<E,A,B,C,R>(proj: E -> (A, B, C) -> R, _ a: A, _ b: B, _ c: C) -> E -> R { | |
return { e in | |
return proj(e)(a,b,c) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment