How to idiomatically rewrite this piece of swift code?


#1

Hello, fellows!
I’m stuck with Scala type system. How to rewrite the following swift code?

protocol Proto {
	associatedtype T
	
	func foo(_:T) -> T
}

class IntProto : Proto {
	let offset : Int
	
	init(_ offset : Int) {
		self.offset = offset
	}
	
	func foo(_ x : Int) -> Int {
		return x + offset
	}
}


class Launcher<P : Proto> {
	let proto : P
	
	init(_ proto : P) {
		self.proto = proto
	}
	
	func launch(_ x : P.T) {
		print(proto.foo(x))
	}
}

Launcher(IntProto(31)).launch(11)

#2

Can you show us what you’ve tried so far and where you’re stuck?


#3

Sure.

I’ve tried to rewrite the following way:

trait Proto {
	type T
  def foo(x : T) : T
}

class IntProto(offset : Int) extends Proto {
    type T = Int
    def foo(x : Int) : Int = x + offset
}

class Launcher(p: Proto) {
  def launch(x : p.T): Unit = {
    println(p.foo(x))
  }
}


object Main {
  def main(args: Array[String]): Unit = { 
  		val launcher = new Launcher(new IntProto(31))
    	launcher.launch(11)
  }
}

Unfortunately, I get “non-private method launch refers to private value p in its type signature (x: Launcher.this.p.T): Unit” error.


#4

See the slight variation to Launcher…
Without it will fail…

Below returns 23

trait Proto {
  type T
  def foo(x: T): T
}

case class IntProto(offset: Int) extends Proto {
  type T = Int

  def foo(x: Int): Int =
    x + offset
}

case class Launcher[P <: Proto](p: P) {
  def launch(x: p.T): Unit = {
    println(p.foo(x))
  }
}

object Test extends App {
  Launcher(IntProto(12)).launch(11)
}

#5

Ok, I got it. Thank you.