Skip to content

Instantly share code, notes, and snippets.

@irace
Created May 1, 2015 21:30
Show Gist options
  • Save irace/2f5e2253377704aa7dd0 to your computer and use it in GitHub Desktop.
Save irace/2f5e2253377704aa7dd0 to your computer and use it in GitHub Desktop.
4:48 PM] heathborders: You can do this in swift
[4:50 PM] heathborders: You need to make a Request protocol:
```protocol RequestProtocol {
typealias ResourceType
var resource: ResourceType { get }
}
```
(edited)
[4:52 PM] heathborders: and then a capturing class:
``` class RequestOf<ResourceType>: RequestProtocol {
let _resource: ResourceType
var resource: ResourceType {
return _resource
}
init<RequestProtocolType: RequestProtocol where RequestProtocolType.ResourceType == ResourceType>(_ requestProtocol: RequestProtocolType) {
_resource = requestProtocol.resource
}
}
```
(edited)
[4:52 PM] gfontenot: use triple backticks for code blocks
[4:52 PM] gfontenot: it'll make that much easier to read
[4:53 PM] gfontenot: on both sides
[4:53 PM] gfontenot:
``````
[4:55 PM] heathborders: Finally, you can put all the `RequestOf`s in an array:
```let requestOfs: RequestOf<AnyObject> = [
RequestOf(Request(resource: User()),
RequestOf(Request(resource: Order()),
]
```
[4:56 PM] heathborders: I don’t know if this is a higher-kinded type, but I use this pattern all over the place
[4:56 PM] gfontenot: it's a way to simulate higher kinded types
5:00 PM] heathborders: basically, you use the *Of class to capture the protocol type you receive via the init method.
[5:01 PM] heathborders: Also, it’s important that `RequestOf` implement `RequestProtocol`, so you can be sure you can delegate everywhere, and so that a `RequestOf` is a `RequestProtocol`
[5:01 PM] segiddins: isnt that type erasure?
[5:02 PM] heathborders: no
[5:02 PM] heathborders: it’s the opposite. It’s type capture. :simple_smile:
[5:02 PM] heathborders: Swift doesn’t allow a protocol to capture a type, but a class can
[5:19 PM] eridius: what do you mean by that?
[5:21 PM] heathborders: I mean that you can’t say `let userRequestProtocol: RequestProtocol<User> = Request(response = User())` (edited)
[5:21 PM] eridius: That `RequestProtocol` protocol is not "object-safe" (meaning it can't be treated as a protocol object, because it has associated types and there's no way to represent that with protocol objects). `RequestOf` is a concrete wrapper that lets you represent the associated type in a way that the type system can handle
[5:22 PM] heathborders: yes
[5:22 PM] eridius: it is an annoying limitation of Swift that you cannot have type parameters on protocols
[5:22 PM] heathborders: yes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment