Extending a generic type where T == Void


(Benedict Cohen) #1

I have an enum that represents the states of a task:

enum TaskState<InType, OutType>{
case preparing
case ready(InType)
case executing(InType, TaskIdentifier)
case success(InType, OutType)
case failure(InType, Error)

mutating func transition(toReady: InType) {...}

}

//Usage
var locationSearchTaskState: TaskState<String, [Location]> = .preparing
//...
locationSearchTaskState.transition(toReady: text)

This works as desired for most cases. Not all tasks, however, have an input:

var topLocationsTaskState<Void, [Location]> = .ready( () )

In this case we have to pass the empty tuple as the value which is ugly. I'd like to add some sugar to make this nicer. Something along the lines of:

extension TaskState where InType: Void {...}

Of course this doesn't work because Void is not a protocol (nor can it conform to a protocol because it's just a tuple). So my question: How can I extend a generic type when the generic parameter is Void? Are there alternative ways to model this problem?

Cheers
Ben


(Dave Abrahams) #2

There's a horrible hack you can use:

protocol TaskStateProtocol {
  associatedtype InType
  mutating func transition(toReady: InType)
}
extension TaskState : TaskStateProtocol {}

extension TaskStateProtocol where InType == Void {
  // ... <==== put your stuff here
}

HTH,

···

on Tue Aug 09 2016, Benedict Cohen <swift-users-AT-swift.org> wrote:

I have an enum that represents the states of a task:

enum TaskState<InType, OutType>{
case preparing
case ready(InType)
case executing(InType, TaskIdentifier)
case success(InType, OutType)
case failure(InType, Error)

mutating func transition(toReady: InType) {...}

}

//Usage
var locationSearchTaskState: TaskState<String, [Location]> = .preparing
//...
locationSearchTaskState.transition(toReady: text)

This works as desired for most cases. Not all tasks, however, have an input:

var topLocationsTaskState<Void, [Location]> = .ready( () )

In this case we have to pass the empty tuple as the value which is ugly. I'd like to add some sugar to make this nicer. Something along the lines of:

extension TaskState where InType: Void {...}

Of course this doesn't work because Void is not a protocol (nor can it
conform to a protocol because it's just a tuple). So my question: How
can I extend a generic type when the generic parameter is Void? Are
there alternative ways to model this problem?

--
-Dave