It occurred to me how opaques – basically being a wrapper – are actually quite similar to delegators:
trait Artist {
def name: String
def create(): Art
}
class Painter(override val name: String) extends Artist {
override def create(): Art = ???
}
opaque OpaqueConArtist { inspiration: Artist =>
def name: String = s"${inspiration.name} the original"
}
delegator DelegatorConArtist { insporation: Artist =>
def name: String = s"${inspiration.name} the original"
}
val bansky = new Painter("Bansky")
val opaqueArtist = OpaqueConArtist(bansky)
val delegatorArtist = DelegatorConArtist(bansky)
opaqueArtist.name == delegatorArtist.name
opaqueArtist.create() // doesn't compile
delegatorArtist.create() // == bansky.create()
def introduce(artist: Artist): String = s"${artist.name} belongs in a museum"
introduce(bansky)
introduce(opaqueArtist) // doesn't compile
introduce(delgetorArist)
1.isInstanceOf[OpaqueConArtist] // doesn't compile
1.isInstanceOf[DelegatorConArtist] // probably compiles