I\'m trying out some examples from the Swift book, namely the matrix example they have which introduces subscript options. This is the code I have:
struct Ma
Here's for your second question (but you really should ask two separate questions):
@infix func + <T> (m1: Matrix<T>, m2: Matrix<T>) -> Matrix<T> { ... }
For your first question: before solving it, here's the syntax to define multiple constraints for type parameter:
struct Matrix<T where T: Equatable, T: Summable, T: Multipliable> {...}
or, as GoZoner writes in the comments:
struct Matrix<T: protocol<Equatable, Summable, Multipliable>> {...}
But we're not going to need it. First, define a new protocol and list the operations that you need. You can even make it extend Equatable:
protocol SummableMultipliable: Equatable {
func +(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
}
Then, provide extensions for the types that you want to conform. Here, for Int and Double, the extensions are even empty, as the implementation of the needed ops is built-in:
extension Int: SummableMultipliable {}
extension Double: SummableMultipliable {}
Then, declare your type constraint on the type parameter:
struct Matrix<T: SummableMultipliable> { ... }
Finally, you can write stuff like this:
let intMat = Matrix<Int>(rows: 3, columns: 3, initialValue: 0)
let doubleMat = Matrix<Double>(rows: 3, columns: 3, initialValue: 0)
let i: Int = intMat[0,0]
let d: Double = doubleMat[0,0]
The last thing you'll need is to insert the type constraint in the definition of your operator:
@infix func + <T: SummableMultipliable> (m1: Matrix<T>, m2: Matrix<T>) -> Matrix<T> { ... }
For Question 1 start by defining a protocol
protocol Summable { func ignore () }
It has a throw away method. Then add it as an extension to the things that you want to be summable.
extension Int: Summable { func ignore () {} }
[Note: I tried the above w/o a throw away method but got a failure; I suspect Swift needed something, anything in the protocol.]
Now a test
35> protocol Summable { func ignore () }
36> extension Int: Summable { func ignore () {} }
37> func testing<T: Summable> (x: T) -> T { return x }
38> testing(1)
$R16: (Int) = 1
39> testing(1.2)
<REPL>:39:1: error: cannot convert the expression's type '$T1' to type 'Summable'
testing(1.2)
^~~~~~~~~~~~
For Question 2, [edit] Use the following
@infix func +<T: Summable> (m1: Matrix<T>, m2: Matrix<T>) -> Matrix<T> { ... }
[Note: I tried the above in the REPL, which didn't work. But it works in a file (probably defines a 'global environment' which the REPL doesn't)]