I am experimenting with message-based architecture in Swift. I am trying to do something similar to the Elm Architecture, for example. This is how my code looks:
enum SideEffect<Message> {
case sendRequest((String) -> Message)
}
protocol Component {
associatedtype Message
mutating func send(msg: Message) -> [SideEffect<Message>]
}
struct State: Component {
var something: String?
enum Message {
case downloadSomething
case receiveResponse(String)
}
mutating func send(msg: Message) -> [SideEffect<Message>] {
switch msg {
case .downloadSomething:
return [.sendRequest(Message.receiveResponse)]
case .receiveResponse(let response):
something = response
return []
}
}
}
So the state is modelled by State and you can change it by sending Messages. If there are any side effects to compute, they are returned as a SideEffect message and will be taken care of by someone else. Each SideEffect message takes a “callback” argument, a Message to send when the side effect is finished. This works great.
Now, what if I want to have a generic side effect message? I would like to have something like this:
struct Request<ReturnType> { … }
And have a related side effect to load the request and return a value of type ReturnType:
enum SideEffect<Message> {
case sendRequest(Request<T>, (T) -> Message)
}
But this (obviously) doesn’t compile, as the case would have to be generic over T. I can’t make the whole SideEffect generic over T, since there’s other side effects that have nothing to do with T.
Can I somehow create a SideEffect message with a Request<T> that would later dispatch a Message with T? (I think I want something like this feature discussed on swift-evolution.)