Created
November 2, 2019 23:28
-
-
Save bkase/f9e338729eb0ef036b4e5b5b81684fc5 to your computer and use it in GitHub Desktop.
Comonadic UIs in SwiftUI with Bow
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 Bow | |
import SwiftUI | |
public typealias Component<W: Comonad, V: View> = | |
Kind<W, SwiftUIBackendOf<CoOf<W, ()>, V>> | |
func const<A,B>(_ x: A) -> (B) -> A { return { _ in x } } | |
public final class ComponentView<W: Comonad, V: View>: View { | |
private var component: Component<W, V> | |
init(component: Component<W, V>) { | |
self.component = component | |
} | |
private func send(m: CoOf<W, ()>) { | |
self.component = | |
Co<W, ()>.pair().zap( | |
self.component.duplicate() | |
.map(const), ga: m) | |
} | |
public var body: V { | |
return SwiftUIBackend | |
.fix(component.extract()) | |
.component(send) | |
} | |
} |
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 Bow | |
import SwiftUI | |
enum CoStore { // isomorphic to State monad afaik | |
static func modify<S>(_ f: @escaping (S) -> S) -> Co<StorePartial<S>, ()> { | |
Co { w in | |
let store = Store.fix(w) | |
return store.render(f(store.state))(()) | |
} | |
} | |
} | |
@available(OSX 10.15, *) | |
func counter() -> Component<StorePartial<Int>, Button<Text>> { | |
return Store(state: 0) { count in | |
SwiftUIBackend { send in | |
Button<Text>("Total: \(count)") { | |
send(CoStore.modify{$0+1}) | |
} | |
} | |
} | |
} |
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 Bow | |
import BowEffects | |
import SwiftUI | |
@available(OSX 10.15, *) | |
public final class ForSwiftUIBackend<V: View> {} | |
@available(OSX 10.15, *) | |
public typealias SwiftUIBackendOf<A, V: View> = Kind<ForSwiftUIBackend<V>, A> | |
@available(OSX 10.15, *) | |
public class SwiftUIBackend<A, V: View> : SwiftUIBackendOf<A, V> { | |
public static func fix(_ ui : SwiftUIBackendOf<A, V>) -> SwiftUIBackend<A, V> { | |
ui as! SwiftUIBackend<A, V> | |
} | |
let component : (@escaping (A) -> ()) -> V | |
init(_ component: @escaping (@escaping (A) -> ()) -> V) { | |
self.component = component | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment