I know view bounds may be deprecated soon. Please ignore that.
The following code compiles if only one of the last 3 implicit conversions are uncommented. Is this a compiler bug?
object Viewable extends App {
/** Speed of light in m/s */
val C: Double = 299293458d
/** @param weight in kilograms */
case class Matter(name: String, weight: Double) {
/** @return matter-energy equivalence in megajoules */
def energy: Double = weight * C * C / 1000000d
def megaJouleMsg: String = f"$name's mass-energy equivalence is $energy%.0f megajoules."
}
case class Animal(name: String, height: Double, weight: Double)
case class Vegetable(name: String, height: Double, weight: Double)
case class Mineral(name: String, weight: Double)
case class Bug(name: String, height: Double, weight: Double, canFly: Boolean)
case class Whale(name: String, height: Double, weight: Double, hasTeeth: Boolean)
case class AppleTree(name: String, height: Double, weight: Double, age: Int)
case class Grass(name: String, height: Double, weight: Double, edible: Boolean)
case class Sand(name: String, color: String, weight: Double)
case class Rock(name: String, color: String, weight: Double)
implicit def sandToMineral(sand: Sand) = Mineral(sand.name, sand.weight)
implicit def rockToMineral(rock: Rock) = Mineral(rock.name, rock.weight)
implicit def appleTreeToVegetable(tree: AppleTree) = Vegetable(tree.name, tree.height, tree.weight)
implicit def grassToVegetable(grass: Grass) = Vegetable(grass.name, grass.height, grass.weight)
implicit def bugToAnimal(bug: Bug) = Animal(bug.name, bug.height, bug.weight)
implicit def whaleToAnimal(whale: Whale) = Animal(whale.name, whale.height, whale.weight)
implicit def animalToMatter[X <% Animal](animal: X) = Matter(animal.name, animal.weight)
implicit def vegetableToMatter[X <% Vegetable](vegetable: X) = Matter(vegetable.name, vegetable.weight)
implicit def mineralToMatter[X <% Mineral](mineral: X) = Matter(mineral.name, mineral.weight)
println(Animal("Poodle", 1.0, 8.0).megaJouleMsg)
println(AppleTree("Spartan", 2.3, 26.2, 12).megaJouleMsg)
println(Rock("Quartz crystal", "white", 2.3).megaJouleMsg)
}
The error messages are:
type mismatch;
found : solutions.Viewable.Animal
required: ?{def megaJouleMsg: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method animalToMatter in object Viewable of type [X](animal: X)(implicit evidence$1: X => solutions.Viewable.Animal)solutions.Viewable.Matter
and method vegetableToMatter in object Viewable of type [X](vegetable: X)(implicit evidence$2: X => solutions.Viewable.Vegetable)solutions.Viewable.Matter
are possible conversion functions from solutions.Viewable.Animal to ?{def megaJouleMsg: ?}
println(Animal("Poodle", 1.0, 8.0).megaJouleMsg)
^
type mismatch;
found : solutions.Viewable.AppleTree
required: ?{def megaJouleMsg: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method animalToMatter in object Viewable of type [X](animal: X)(implicit evidence$1: X => solutions.Viewable.Animal)solutions.Viewable.Matter
and method vegetableToMatter in object Viewable of type [X](vegetable: X)(implicit evidence$2: X => solutions.Viewable.Vegetable)solutions.Viewable.Matter
are possible conversion functions from solutions.Viewable.AppleTree to ?{def megaJouleMsg: ?}
println(AppleTree("Spartan", 2.3, 26.2, 12).megaJouleMsg)
^