Skip to content

Instantly share code, notes, and snippets.

@gakuzzzz
Created January 19, 2016 20:23
Show Gist options
  • Save gakuzzzz/aad6ef8b5e235dc61ed8 to your computer and use it in GitHub Desktop.
Save gakuzzzz/aad6ef8b5e235dc61ed8 to your computer and use it in GitHub Desktop.
Generics の Abstract Type Member によるエミュレートの implicit parameter
scala> :paste
// Entering paste mode (ctrl-D to finish)

trait MyOrdering {
  type E
  def compare(a: E, b: E): Int
}
object MyOrdering {

  implicit val intOrdering: MyOrdering { type E = Int } = new MyOrdering {
    type E = Int
    def compare(a: Int, b: Int): Int = a - b
  }

  implicit val stringOrdering: MyOrdering { type E = String } = new MyOrdering {
    type E = String
    def compare(a: String, b: String): Int = a compareTo b
  }
}

trait MyList { self =>

  type E

  def head: E
  def last: E

  def max(implicit ord: MyOrdering { type E = self.E }): E = {
    if (ord.compare(head, last) > 0) head else last
  }

}

class IntList(val head: Int, val last: Int) extends MyList {

  type E = Int

}

class StringList(val head: String, val last: String) extends MyList {

  type E = String

}

val i = new IntList(10, 20)
val s = new StringList("bb", "aa")

// Exiting paste mode, now interpreting.

defined trait MyOrdering
defined module MyOrdering
defined trait MyList
defined class IntList
defined class StringList
i: IntList = IntList@33c405d5
s: StringList = StringList@49530de7

scala> i.max
res0: i.E = 20

scala> s.max
res1: s.E = bb

scala>

ファッ!?

scala> class LongList(val head: Long, val last: Long) extends MyList {
     |   type E = Long
     | }
defined class LongList

scala> val l = new LongList(20L, 10L)
l: LongList = LongList@6e9c814

scala> l.max
<console>:12: error: could not find implicit value for parameter ord: MyOrdering{type E = l.E}
              l.max
                ^

ウゴイタァァァ!!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment