// The output is // List(Apple(1:Semerenka), Apple(1:Gloster), Apple(1:Red Prince)) // List(Orange(1:Turkey), Orange(1:Egypt)) // List(Peach(1:Yes!), Peach(1:Sure!)) // List(Apple(2:Semerenka), Apple(2:Gloster), Apple(2:Red Prince)) // List(Orange(2:Turkey), Orange(2:Egypt)) // List(Peach(2:Yes!), Peach(2:Sure!)) trait Session { override def toString: String = this match { case ReadOnlySession ⇒ "1" case NormalSession ⇒ "2" } } object ReadOnlySession extends Session object NormalSession extends Session object Test { def main(args: Array[String]): Unit = { implicit val session: Session = ReadOnlySession val normSession = NormalSession val list1 = genericList1(Apple.findAll) val list2 = genericList2(Orange.findAll) val list3 = genericList3(Peach.findAll()(_)) val list4 = genericList1(Apple.findAll()(normSession)) val list5 = genericList2(() ⇒ Orange.findAll()(normSession)) val list6 = genericList3(Peach.findAll()(_))(normSession) println(list1) println(list2) println(list3) println(list4) println(list5) println(list6) } def genericList1[A](method: ⇒ List[A]): List[A] = { method } def genericList2[A](method: () ⇒ List[A]): List[A] = { method() } def genericList3[A](method: Session ⇒ List[A])(implicit session: Session): List[A] = { method(session) } case class Apple(sort: String) object Apple { def findAll()(implicit s: Session): List[Apple] = { List(Apple(s"$s:Semerenka"), Apple(s"$s:Gloster"), Apple(s"$s:Red Prince")) } } case class Orange(country: String) object Orange { def findAll()(implicit s: Session): List[Orange] = List(Orange(s"$s:Turkey"), Orange(s"$s:Egypt")) } case class Peach(tasty: String) object Peach { def findAll()(implicit s: Session): List[Peach] = List(Peach(s"$s:Yes!"), Peach(s"$s:Sure!")) } }