-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type safety on Workflow Launch Args #22
Comments
This is an absolutely insane example but it showcases a little of how this might be able to work. It's heavily inspired by Combine and not quite right still, but I think it demonstrates how this could be accomplished at all. import Foundation
protocol PThing {
associatedtype Upstream = Never
associatedtype T
}
enum AllThings {
}
extension PThing {
func then<V>(_ v: V) -> AllThings.CThing<Self, V> {
AllThings.CThing<Self, V>(v)
}
func firstType<U>() -> U.T.Type where U: PThing, U == Upstream {
U.T.self
}
func firstType() -> T.Type where Upstream == Never {
T.self
}
}
extension AllThings {
class CThing<Upstream, T>: PThing {
typealias Upstream = Upstream
typealias T = T
init(_ t: T) { }
}
}
class Thing<T>: PThing {
typealias Upstream = Never
init(_ t: T) { }
func then<PT: PThing>(_ pt: PT) -> PT where PT.Upstream == Upstream {
return pt
}
}
var a = Thing<String>("")
// NOTE: The complex type below is AllThings.CThing<Thing<String>, Bool>
print(a.then(true).firstType()) // prints "String" Now imagine extending this example to the protocol PThing where T: FlowRepresentable {
associatedtype Upstream = Never
associatedtype T
} Then when you call launch it uses the same kind of logic that lives in This example however is incomplete for several reasons:
|
This seems like a great idea, not sure when it will be a focus for us, but we're keeping an eye on it! 👍🏻 |
Update: The SwiftUI approach we've taken (or even alternative paths we've considered) tends to give us this, the issue isn't all the way closed since it'd be nice to see it in UIKit too. |
I feel like this might be part of a bigger issue request to convert workflow UIKit to the more fluent API in SwiftUI. I'm thinking the change would be breaking though so we may want to batch a couple of changes together and do it all at once. |
Is your feature request related to a problem? Please describe.
It's unfortunate that when I launch a Workflow the arguments I pass to launch it are not typed. So I don't get a compiler check.
Describe the solution you'd like
The short version? I want
launch
to be smart enough to know what the first item in the Workflow expects for itsWorkflowInput
and have that type be what I pass as args. Additionally if that type isNever
I want to be forbidden from passing args and if that type is notNever
I want to be forced to pass args.Potential solution:
Combine has Publishers that end up chaining in an interesting way with Generics that we could rip off. For example
Workflow(FR1.self) creates a Workflow. But Workflow(FR1.self).thenProceed(with: FR2.self) creates
Workflow<FR2, Workflow<FR1>>
or...something like that? The solution is not totally ironed out in my head, but the premise is that you'd be able to backtrack through all the nestedWorkflow
s until you got to the first one, thus knowing theFlowRepresentable
type that comes first and asserting launch happens with the correct input.Describe alternatives you've considered
I suppose there's a simpler approach that is a little less consumer friendly where they just pass the
FlowRepresentable
type that is going to be launched and we steal theWorkflowInput
from it. I'm not really a fan because it adds an unneeded parameter.The text was updated successfully, but these errors were encountered: