Poly function cannot resolve implicit, works with explicit invocation
elefthei opened this issue · comments
Lef Ioannidis commented
I would like to call polyToString
recursively and polymorphically instead of manually specifying the caseManager
implicit to use. Since it works in all other members, it is strange that the Poly does not resolve the implicit in this case. Look at the XXX
comment.
// A sealed trait (sum) and some case classes (products)
sealed trait Entity
case class Employee(name : String, uid: Int) extends Entity
case class Manager(name: String) extends Entity
case class Department(name: String, manager : Manager, employees: List[Employee]) extends Entity
// Test case
object Data {
val a: Employee = new Employee("a", 100)
val b: Employee = new Employee("b", 101)
val c: Employee = new Employee("c", 102)
val john: Manager = new Manager(name = "John Boss")
val sales: Department = new Department("Sales", manager = john, employees = List(a, b, c))
}
// Enter Polymorphic functions
object polyToString extends Poly1 {
// utility, indent a string
private def indent(n : Int, s: String) : String = " ".repeat(n) + s
implicit def caseEmployee = use((e : Employee) => s"EmployeeID: ${e.uid} * Name: ${e.name}")
implicit def caseListEmployees = use ((le: List[Employee]) =>
le.map(polyToString).map(indent(4, _)).mkString("\n"))
implicit def caseManager = use((m : Manager) => s"Manager-In-Chief: ${m.name}")
implicit def caseDepartment = use((d: Department) =>
s"Glorious department of ${d.name}\n"
+ indent(2, polyToString(d.manager : Manager)) + "\n" //XXX: This works if I call caseManager directly, looks like a call to `polyToString` cannot resolve the implicit for Manager
+ polyToString(d.employees))
implicit def caseDefault[A] = use((a: A) => {
println(s"Warning: Using default function for ${a.toString}")
a.toString
})
}
object Main extends App {
import Data._
println(polyToString(sales))
}
Miles Sabin commented
The example is a little bit dense for me to be able to say at a glance, but I think this is most likely an implicit ambiguity/priority issue. I suggest you take it to the shapeless gitter channel and ask for advice there.
If you establish that there is a bug in shapeless, please reopen this issue.