Skip to content

Instantly share code, notes, and snippets.

@chrisfarber
Last active February 27, 2021 14:53
Show Gist options
  • Save chrisfarber/b4b0eddca2bb54bf36f7babeb1cfa8a1 to your computer and use it in GitHub Desktop.
Save chrisfarber/b4b0eddca2bb54bf36f7babeb1cfa8a1 to your computer and use it in GitHub Desktop.
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