I'm working in Swift 4.
I want to define a Problem.
A Problem consists of a Question and an Answer.
The Question might be any of: String, Int, [Int], Image, [Image] or some new Type not defined or could be some combination of the above.
The Answer might also be any of the above but a given Question can have an Answer of a different type.
(e.g. question = (Image, "What type of animal is this?), answer = ("A Cat") )
So I thought protocols would be the way to go:
protocol Posable {
var pose: String { get }
}
protocol Answerable: Hashable {
var answer: String { get }
}
protocol Puzzle {
var problem: Posable { get }
var solution: Answerable { get }
}
I made Answerable Hashable because I want to be able to compare Answers and create sets of Answers.
But I get on the solution: Answerable line:
'Protocol 'Answerable' can only be used as a generic constraint because it has Self or associated type requirements.
I understand why that is but...
Can anyone make any suggestions about how to implement this so that I don't run into that problem?
I'm keen to implement with protocols if possible, partly so that I learn about them.
I would solve it with generics :
import UIKit
struct Posable<T> {
var pose: T
}
struct Answerable<T> {
var answer: T
}
extension Answerable: Equatable where T: Equatable {
static func ==(lhs: Answerable<T>, rhs: Answerable<T>) -> Bool {
return lhs.answer == rhs.answer
}
}
extension Answerable: Hashable where T: Hashable {
var hashValue: Int {
return answer.hashValue
}
}
struct Puzzle<T, U> {
var problem: Posable<T>
var solution: Answerable<U>
}
let image = UIImage() // Image of a cat
let pose = Posable<(UIImage, String)>(pose: (image, "What type of animal is this?"))
let solution = Answerable<String>(answer: "A cat")
let myPuzzle = Puzzle<(UIImage, String), String>(problem: pose, solution: solution)
Generics allow you to make very reusable code! Here you can use any class as a question or as an anwser.
With Swift type inherence : you also get to simplify the initialization :
let image = UIImage() // Image of a cat
let pose = Posable(pose: (image, "What type of animal is this?"))
let solution = Answerable(answer: "A cat")
let myPuzzle = Puzzle(problem: pose, solution: solution)