Pro Yearly is on sale from $80 to $50! »

Intro to typeclass in Scala

Intro to typeclass in Scala

D1c239babc57d9bbb8314f72c09844c1?s=128

Kazuhiro Ichikawa

June 28, 2019
Tweet

Transcript

  1. *OUSPUPUZQFDMBTTJO4DBMB 4DBMBʹ͓͚ΔܕΫϥεೖ໳ 'JWF*OD !QIFOBO

  2. ໨࣍ $POUFOUT  6OEFSTUBOEJOHUZQFDMBTTFT  6TJOHUZQFDMBTTFTJO4DBMB  6TJOHUZQFDMBTTFTJO4DBMB ͜͜ʹ೔ຊޠࣈນ͕ೖΓ·͢

  3. 6OEFSTUBOEJOHUZQFDMBTTFT ܕΫϥεΛཧղ͠Α͏

  4. ܕΫϥε 5ZQFDMBTT w -BOHVBHFDPOTUSVDUUIBUTVQQPSUTBEIPDQPMZNPSQIJTN w "EIPDQPMZNPSQIJTN  w "LJOEPGQPMZNPSQIJTNUIBUBMMPXTEFDMBSJOHGVODUJPOTUIBU DBOCFBQQMJFEGPSBSHVNFOUTPGEJGGFSFOUUZQFT

    w *UJTLOPXOBTPWFSMPBEJOH w 0,4P 8IBUJTUZQFDMBTT ܕΫϥεͬͯԿ ΞυϗοΫϙϦϞʔϑΟζϜͬͯԿ  Φʔόʔϩʔυ ݁ہͲ͏͍͏͜ͱ
  5. ετϥςδύλʔϯ 4USBUFHZQBUUFSO w 0OFPGBEFTJHOQBUUFSOJOUSPEVDFECZ(P' w 3FHBSETBQJFDFPGMPHJDBTBOPCKFDU DBMMFETUSBUFHZ  w &OBCMFTTFMFDUJOHTVJUBCMFTUSBUFHZBUSVOUJNF

    ετϥςδύλʔϯ
 ϩδοΫͷҰ෦ΛΦϒδΣΫτʹͯ͠੾Γସ͑Մೳʹ͢Δ
  6. ετϥςδύλʔϯ 4USBUFHZQBUUFSO SVOͷϩδοΫΛ4USBUFHZΦϒδΣΫτʹ෼཭͠ɺ 4USBUFHZΛ౉͔͢4USBUFHZΛ౉͔͢ͰॲཧΛ෼͚Δ interface/trait Strategy abstract logic() object Strategy2

    def logic() object Strategy1 def logic() def run(strategy:Strategy) = { … strategy.logic() … } DBMM … run(Strategy1) …
  7. ۩ମྫίϯύϨʔλ &YBNQMF$PNQBSBUPS Α͘ར༻͞ΕΔ۩ମྫ͸$PNQBSBUPSͰɺ
 TPSU಺෦Ͱར༻͢Δൺֱؔ਺Λ֎͔Βม͑ΒΕΔ interface/trait Comparator[T] abstract compare(a: T, b:

    T) object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } … sort(list, 
 IntComparator) … DBMM
  8. ۩ମྫίϯύϨʔλ &YBNQMF$PNQBSBUPS 4DBMBͰͷ࣮૷ྫ trait Comparator[T] { def compare(a: T, b:

    T): Int } object IntComparator extends Comparator[Int] { def compare(a: Int, b: Int): Int = a - b } def sort[T](list: List[T], comparator: Comparator[T]): List[T] = { list match { case x :: xs => val (ys, zs) = xs.partition(a => comparator.compare(x, a) > 0) sort(ys, comparator) ++ List(x) ++ sort(zs, comparator) case Nil => Nil } } sort(List(6, 1, 4, 7, 5, 2, 9, 3, 8), IntComparator)
  9. ετϥςδ͸େ఍ͷ৔߹ࣗ໌Ͱ͋Δ 4USBUFHZJTPCWJPVTJONPTUDBTFT w *ONPTUDBTFT XFVTFlOBUVSBMzPSEFSGPSDPNQBSJOHWBMVFT w OVNFSJDBMPSEFSGPSJOUFHFSWBMVFT w DISPOPMPHJDBMPSEFSGPSEBUFWBMVFT w

    /PUFUIBUlOBUVSBMzPSEFSJTEJGGFSFOUCFUXFFOEJGGFSFOUUZQFT w 0CWJPVTTUSBUFHZDBOCFJOGFSSFEGSPNTUBUJDUZQF ܕʹΑͬͯzࣗવͳzετϥςδ͕͋Γɺ
 େ఍͸ͦΕΛ࢖͑͹ྑ͍
  10. ܕΫϥε㲈ܕγεςϜʹΑΓࢧԉ͞Εͨετϥςδύλʔϯ 5ZQFDMBTT㲔TUSBUFHZQBUUFSOBTTJTUFECZUZQFTZTUFN w 5ZQFTZTUFNBVUPNBUJDBMMZTFBSDIFTTVJUBCMFTUSBUFHZ w 1SPHSBNNFSTEPOPUOFFEUPTQFDJGZTUSBUFHZ w 1SPHSBNNFSTDBOEFDMBSFlOBUVSBMzTUSBUFHZGPSBOZUZQF ܕΫϥε͸ཁ͸ετϥςδύλʔϯ ετϥςδΛܕ͔ΒࣗಈͰܾΊΔ࢓૊Έ͕͋Ε͹ྑ͍

  11. ܕΫϥεͱܕΫϥεΠϯελϯε 5ZQFDMBTTBOEUZQFDMBTTJOTUBODF w 5ZQFDMBTTJTBTUSBUFHZJOUFSGBDF PSUSBJU  w l9JTJOTUBODFPGUZQFDMBTT5zNFBOT
 lTUSBUFHZPCKFDUPGUZQF5<9>FYJTUTz 9͕ܕΫϥε5ͷΠϯελϯεͰ͋Δͱ͸ɺ

    5<9>ܕͷετϥςδΦϒδΣΫτ͕࣮૷Ͱ͖Δ͜ͱΛࢦ͢
  12. ܕΫϥεͱܕΫϥεΠϯελϯε 5ZQFDMBTTBOEUZQFDMBTTJOTUBODF ͭ·Γ interface/trait Comparator[T] abstract compare(a: T, b: T)

    object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM … sort(list, 
 IntComparator) …
  13. ܕΫϥεͱܕΫϥεΠϯελϯε 5ZQFDMBTTBOEUZQFDMBTTJOTUBODF ͕͜͜ܕΫϥε interface/trait Comparator[T] abstract compare(a: T, b: T)

    object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM 5ZQFDMBTT … sort(list, 
 IntComparator) …
  14. ܕΫϥεͱܕΫϥεΠϯελϯε 5ZQFDMBTTBOEUZQFDMBTTJOTUBODF *OU$PNQBSBUPS͸$PNQBSBUPS<*OU>Λ࣮૷͍ͯ͠ΔͷͰ interface/trait Comparator[T] abstract compare(a: T, b: T)

    object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM $PNQBSBUPS<*OU> 5ZQFDMBTT … sort(list, 
 IntComparator) …
  15. ܕΫϥεͱܕΫϥεΠϯελϯε 5ZQFDMBTTBOEUZQFDMBTTJOTUBODF *OU͸ܕΫϥε$PNQBSBUPSͷΠϯελϯεͰ͋Δͱ͍͏ interface/trait Comparator[T] abstract compare(a: T, b: T)

    object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM 5ZQFDMBTT *OUJTJOTUBODFPG $PNQBSBUPS $PNQBSBUPS<*OU> … sort(list, 
 IntComparator) …
  16. ܕΫϥε੍໿ 5ZQFDMBTTDPOTUSBJOU w 5ZQFDMBTTDPOTUSBJOUJTBQBSBNFUFSUIBUUBLFTTUSBUFHZ ܕΫϥε੍໿ͱ͸ετϥςδΛͱΔҾ਺Λࢦ͢

  17. ܕΫϥε੍໿ 5ZQFDMBTTDPOTUSBJOU ͭ·Γ interface/trait Comparator[T] abstract compare(a: T, b: T)

    object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM 5ZQFDMBTT *OUJTJOTUBODFPG $PNQBSBUPS $PNQBSBUPS<*OU> … sort(list, 
 IntComparator) …
  18. ܕΫϥε੍໿ 5ZQFDMBTTDPOTUSBJOU TPSUͷ$PNQBSBUPS<5>ܕͷҾ਺͸ܕΫϥε੍໿ interface/trait Comparator[T] abstract compare(a: T, b: T)

    object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM 5ZQFDMBTT 5ZQFDMBTTDPOTUSBJOU *OUJTJOTUBODFPG $PNQBSBUPS $PNQBSBUPS<*OU> … sort(list, 
 IntComparator) …
  19. ܕΫϥεͷΠϯελϯεએݴ 5ZQFDMBTTJOTUBODFEFDMBSBUJPO w *OTUBODFEFDMBSBUJPOEFDMBSFTlOBUVSBMzTUSBUFHZUPUZQF TZTUFN w 5IJTNFBOTUIBUUZQFTZTUFNBVUPNBUJDBMMZVTFTJUGPS BSHVNFOUPGUZQFDMBTTDPOTUSBJOU ܕγεςϜ͕zࣗવͳzετϥςδΛݟ͚ͭΒΕΔΑ͏ʹɺ
 Πϯελϯεએݴͱ͍͏΋ͷ͕ඞཁ

  20. ܕΫϥεͷΠϯελϯεએݴ 5ZQFDMBTTJOTUBODFEFDMBSBUJPO ͭ·Γ interface/trait Comparator[T] abstract compare(a: T, b: T)

    object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM 5ZQFDMBTT 5ZQFDMBTTDPOTUSBJOU *OUJTJOTUBODFPG $PNQBSBUPS $PNQBSBUPS<*OU> … sort(list, 
 IntComparator) …
  21. ܕΫϥεͷΠϯελϯεએݴ 5ZQFDMBTTJOTUBODFEFDMBSBUJPO *OU$PNQBSBUPS͕$PNQBSBUPS<*OU>ͷzࣗવͳz࣮૷Ͱ͋ Δͱએݴ͢Δͱ Πϯελϯεએݴ interface/trait Comparator[T] abstract compare(a: T,

    b: T) object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } DBMM 5ZQFDMBTT 5ZQFDMBTTDPOTUSBJOU %FDMBSFIntComparatorJTOBUVSBMTUSBUFHZ
 GPSComparator[Int] … sort(list, 
 IntComparator) …
  22. ܕΫϥεͷΠϯελϯεએݴ 5ZQFDMBTTJOTUBODFEFDMBSBUJPO TPSUͷҾ਺ʹετϥςδΛ༩͑ͳ͘ͱ΋ܕγεςϜ͕ࣗಈ Ͱ*OU$PNQBSBUPSΛ୳ͯ͠౉ͯ͘͠ΕΔ interface/trait Comparator[T] abstract compare(a: T, b:

    T) object DateComparator def compare
 (a: Date, b: Date) object IntComparator def compare
 (a: Int, b: Int) def sort[T]
 (list:List[T])
 (cmp:Comparator[T]) = { … cmp.compare(…) … } … sort(list) … DBMM 5ZQFDMBTT 5ZQFDMBTTDPOTUSBJOU 5ZQFTZTUFNBVUPNBUJDBMMZ SFTPMWFTUZQFDMBTT
  23. ·ͱΊ 4FDUJPOTVNNBSZ w 5ZQFDMBTT㲔TUSBUFHZJOUFSGBDF w l9JTJOTUBODFPGUZQFDMBTT5zNFBOT
 lTUSBUFHZPCKFDUPGUZQF5<9>FYJTUTz w 5ZQFDMBTTDPOTUSBJOU㲔TUSBUFHZQBSBNFUFS w

    5ZQFDMBTTJOTUBODFEFDMBSBUJPOEFDMBSFTlOBUVSBMzTUSBUFHZ ܕΫϥε͸ετϥςδύλʔϯͰཧղͰ͖Δ
  24. 6TJOHUZQFDMBTTFTJO4DBMB 4DBMBͰܕΫϥεΛ࢖͏

  25. ܕΫϥεͷએݴ 5ZQFDMBTTEFDMBSBUJPO w *O4DBMB UZQFDMBTTJTEFDMBSFEBTBUSBJU ܕΫϥε͸ҰൠʹUSBJUͱͯ͠એݴ͢Δ trait Comparator[T] { def

    compare(a: T, b: T): Int }
  26. ετϥςδΦϒδΣΫτ 4USBUFHZPCKFDU w "OPCKFDUJNQMFNFOUJOHUIFUSBJUPGUZQFDMBTT w 'PMMPXJOHDPEFNFBOTIntJTJOTUBODFPGComparator $PNQBSBUPS<*OU>ͷ࣮૷ ͜Ε͕࣮૷Ͱ͖ΔͷͰ*OU͸$PNQBSBUPSͷΠϯελϯε object IntComparator

    extends Comparator[Int] { def compare(a: Int, b: Int): Int = a - b }
  27. ܕΫϥεΠϯελϯεએݴ 5ZQFDMBTTJOTUBODFEFDMBSBUJPO w “implicit object”JTUZQFDMBTTJOTUBODFEFDMBSBUJPO w 8FDBOEFGJOF“implicit object”POMZXJUIJODMBTTPSPCKFDU EFDMBSBUJPO ΠϯελϯεએݴΛ͢Δʹ͸JNQMJDJUPCKFDUΛ࢖͏

    object Comparators { implicit object IntComparator extends Comparator[Int] { def compare(a: Int, b: Int): Int = a - b } }
  28. ܕΫϥε੍໿ 5ZQFDMBTTDPOTUSBJOU w *O4DBMB QBSBNFUFSXJUI“implicit”LFZXPSEFYQSFTTFT UZQFDMBTTDPOTUSBJOU w "SHVNFOUPGJNQMJDJUQBSBNFUFSJTBVUPNBUJDBMMZTFBSDIFE GSPNEFDMBSFEJNQMJDJUWBMVFTJOTDPQF ܕΫϥε੍໿͸JNQMJDJUύϥϝʔλͰදݱ͢Δ

    def sort[T](list: List[T])(implicit cmp: Comparator[T]): List[T] = { list match { case x :: xs => val (ys, zs) = xs.partition(a => cmp.compare(x, a) > 0) sort(ys) ++ List(x) ++ sort(zs) case Nil => Nil } }
  29. ܕΫϥε੍໿Λ࣋ͭؔ਺ͷ࢖͍ํ 6TBHFPGGVODUJPOXJUIUZQFDMBTTDPOTUSBJOU w 8FDBOVTFsortGVODUJPOXJUIPVUTQFDJGZJOHDPNQBSBUPSBT JUTBSHVNFOU w 8FTIPVMEJNQPSUComparatorsGPSFOBCMJOHJOTUBODFEFDMT JNQMJDJUύϥϝʔλ͸ܕγεςϜ͕ࣗಈͰຒΊͯ͘ΕΔ
 ΠϯελϯεએݴΛJNQPSU͓ͯ͘͠ඞཁ͕͋Δ import

    Comparators._ sort(List(1, 3, 2)) sort(List(“a”, “c”, “b”)) // error: Comparator[String] not found
  30. Πϯελϯεએݴͷଞͷํ๏ "OPUIFSXBZPGJOTUBODFEFDMBSBUJPO w “implicit def”XJUIOPQBSBNFUFSJTBMTPJOTUBODFEFDMBSBUJPO w 5IJTJTVTFEGPSEFDMBSJOHJOTUBODFXJUIHFOFSJDUZQF ܕҾ਺Λ࣋ͭܕͷΠϯελϯεએݴ͸JNQMJDJUEFGͰߦ͏ object Comparators

    { implicit def setSizeComparator[T]: Comparator[Set[T]] = {
 new Comparator[Set[T]] { def compare(a: Set[T], b: Set[T]): Int = a.size - b.size } } } Note: This comparator is not common for set.
  31. Πϯελϯεએݴͷଞͷํ๏ "OPUIFSXBZPGJOTUBODFEFDMBSBUJPO w *OTUBODFEFDMBSBUJPODBOIBWFUZQFDMBTTDPOTUSBJOU JNQMJDJUEFG΋ܕΫϥε੍໿Λ࣋ͭ͜ͱ͕Ͱ͖ɺ
 ͜ΕʹΑΓෳࡶͳܕͷΠϯελϯεએݴ͕Ͱ͖Δ object Comparators { implicit

    def tupleComparator[T1, T2] (implicit cmp1: Comparator[T1], cmp2: Comparator[T2]): Comparator[(T1, T2)] = {
 new Comparator[(T1, T2)] { def compare(a: (T1, T2), b: (T1, T2)): Int = { val res1 = cmp1.compare(a._1, b._1) if (res1 == 0) cmp2.compare(a._2, b._2) else res1 } } } }
  32. ܕΫϥεͷϝιουͷ࢖͍ํ 6TJOHNFUIPEPGUZQFDMBTT w 5PJOWPLFcompareNFUIPE XFOFFE$PNQBSBUPSJOTUBODF w 8FDBOPCUBJOUZQFDMBTTJOTUBODFCZimplicitlyNFUIPE ܕΫϥεͷϝιουΛݺͿʹ͸ܕΫϥεΠϯελϯε͕ඞཁ JNQMJDJUMZͰܕΫϥεΠϯελϯεΛऔಘͰ͖Δ import

    Comparators._ IntComparator.compare(1, 2) implicitly[Comparator[(Int, Int)]].compare((1, 2),(3, 4))
  33. JNQMJDJUMZ<ʜ>DPNQBSF B C JTOPUJOUVJUJWF w 8FXBOUUPXSJUF“a > b”SBUIFSUIBO“….compare(a, b) >

    0” w 8FEPOPUXBOUUPFYQMJDJUMZXSJUFUZQFDMBTTJOTUBODF ܕΫϥεΠϯελϯεΛ໌ࣔతʹॻ͖ͨ͘ͳ͍ʂ import Comparators._ if (implicitly[Comparator[(Int, Int)]].compare((1, 2),(3, 4)) > 0) { … } if ((1, 2) > (3, 4)) { … } ௚ײతʹ෼͔ΓͮΒ͍
  34. ܕΫϥεΠϯελϯεͷͨΊͷ֦ுϝιου &YUFOTJPONFUIPETGPSUZQFDMBTTJOTUBODFT w 8FDBOEFDMBSFFYUFOTJPONFUIPECZ“implicit class” w “implicit class”DBOBMTPUBLFTUZQFDMBTTDPOTUSBJOU JNQMJDJUDMBTTͰطଘΫϥεʹϝιουΛੜ΍ͤΔ ܕ੍໿Λ͚ͭΕ͹ܕΫϥεΠϯελϯεͰͷΈ࢖͑ΔΑ͏ʹ

    object ComparatorSyntax { implicit class ComparatorOps[T](a: T) (implicit cmp: Comparator[T]) {
 def > (b: T): Boolean = cmp.compare(a, b) > 0 } } import Comparators._ import ComparatorSyntax._ (1, 2) > (2, 4) // return false
  35. 4DBMBʹ͓͚ΔJNQMJDJUͷҙຯ *NQMJDJUTJO4DBMB 4DBMBͰ͸༷ʑͳҙຯͰJNQMJDJU͕࢖ΘΕ͍ͯΔ no parameters one parameter implicit parameters implicit

    parameter typeclass constraint - - implicit val implicit object instance declaration - - implicit class Error! extension methods ◦ implicit def instance declaration implicit conversion ◦
  36. 4DBMBͷܕΫϥεϥΠϒϥϦ 5ZQFDMBTTMJCSBSJFTJO4DBMB w 5IFSFBSFUXPNBKPSMJCSBSJFT w 4DBMB[ w $BUT w 5IJTTMJEFCSJFGMZEFTDSJCFTQBDLBHFTUSVDUVSFPGUIFN

    w 6TFSTOFFEUPJNQPSUUZQFDMBTTFT JOTUBODFEFDMBSBUJPOT  BOEFYUFOTJPONFUIPETGPSVTJOHUIFTFMJCTXFMM ೋେܕΫϥεϥΠϒϥϦ4DBMB[ $BUT ͜ΕΒΛ্ख͘࢖͏ʹ͸ύοέʔδߏ଄Λ஌͓ͬͯ͘ඞཁ
  37. 4DBMB[ͷύοέʔδߏ੒ 1BDLBHFTUSVDUVSFPG4DBMB[ w TDBMB[  w UZQFDMBTTEFDMBSBUJPOT w TDBMB[TUE 

    w JOTUBODFEFDMBSBUJPOTPGDPNNPOUZQFT w TDBMB[TZOUBY  w FYUFOTJPONFUIPET TDBMB[TUEҎԼʹΠϯελϯεએݴ TDBMB[TZOUBYҎԼʹ֦ுϝιου͕ఆٛ͞Ε͍ͯΔ
  38. $BUTͷύοέʔδߏ੒ 1BDLBHFTUSVDUVSFPG$BUT w DBUT  w UZQFDMBTTEFDMBSBUJPOT w DBUTJOTUBODFT 

    w JOTUBODFEFDMBSBUJPOTPGDPNNPOUZQFT w DBUTTZOUBY  w FYUFOTJPONFUIPET $BUT΋ࣅͨΑ͏ͳύοέʔδͷߏ଄Λ͍ͯ͠Δ
  39. 6TJOHUZQFDMBTTFTJO4DBMB 4DBMBͰܕΫϥεΛ࢖͏

  40. 4DBMBʹ͓͚ΔܕΫϥεએݴ 5ZQFDMBTTEFDMBSBUJPOJO4DBMB w 5ZQFDMBTTJTEFDMBSFEBTBUSBJU 4DBMBͱಉ༷ʹܕΫϥεͷએݴ͸USBJU trait Comparator[T] { def compare(a:

    T, b: T): Int }
  41. 4DBMBʹ͓͚ΔܕΫϥεΠϯελϯεએݴ 5ZQFDMBTTJOTUBODFEFDMBSBUJPOJO4DBMB • “delegate for”JTJOTUBODFEFDMBSBUJPO • 5IFOBNFPGEFMFHBUFJOTUBODFJTPQUJPOBM Πϯελϯεએݴ͸৽ͨʹEFMFHBUFGPSߏจ͕ಋೖ object Comparators

    { delegate IntComparator for Comparator[Int] { def compare(a: Int, b: Int): Int = a - b } delegate [T] for Comparator[Set[T]] { def compare(a: Set[T], b: Set[T]): Int = a.size - b.size } }
  42. 4DBMBʹ͓͚ΔܕΫϥε੍໿ͷॻ͖ํ 5ZQFDMBTTDPOTUSBJOUJO4DBMB w *O4DBMB QBSBNFUFSMJTUGPMMPXJOH“given”LFZXPSEFYQSFTTFT UZQFDMBTTDPOTUSBJOU ܕΫϥε੍໿͸HJWFOΩʔϫʔυͰએݴ͢Δ def sort[T](list: List[T])

    given (cmp: Comparator[T]): List[T] = { list match { case x :: xs => val (ys, zs) = xs.partition(a => cmp.compare(x, a) > 0) sort(ys) ++ List(x) ++ sort(zs) case Nil => Nil } }
  43. ܕΫϥε੍໿Λ࣋ͭؔ਺ͷ࢖͍ํ 6TBHFPGGVODUJPOXJUIUZQFDMBTTDPOTUSBJOU w 8FTIPVMEJNQPSUJOTUBODFEFDMBSBUJPOTCZ“import delegate” w 8FDBOFYQMJDJUMZHJWFBOBSHVNFOUGPSUZQFDMBTTDPOTUSBJOU CZVTJOH“given”LFZXPSE ΠϯελϯεએݴͷΠϯϙʔτʹ͸JNQPSUJNQMJFEΛར༻ HJWFOʹΑΓܕΫϥε੍໿ͷ࣮Ҿ਺Λ໌ࣔతʹ༩͑ΒΕΔ

    import delegate Comparators._ sort(List(1, 3, 2)) sort(List(“a”, “c”, “b”)) given stringComparator
  44. ܕΫϥεΠϯελϯεͷͨΊͷ֦ுϝιου &YUFOTJPONFUIPETGPSUZQFDMBTTJOTUBODFT w 4DBMBTVQQPSUTOFXTZOUBYGPSEFDMBSJOHFYUFOTJPONFUIPET w /FXTZOUBYUBLFTBQBSBNFUFSCFGPSFNFUIPEOBNFBOEUIF NFUIPEJTUSFBUFEBTJOTUBODFNFUIPEPGUIFQBSBNFUFSUZQF 4DBMBͰ͸ΑΓ௚઀తʹ֦ுϝιουΛαϙʔτ͍ͯ͠Δ trait Comparator[T]

    { def compare(a: T, b: T): Int def (a: T) > (b: T): Boolean = compare(a, b) > 0 def (a: T) < (b: T): Boolean = compare(a, b) < 0 }
  45. ܕΫϥεΠϯελϯεͷͨΊͷ֦ுϝιου &YUFOTJPONFUIPETGPSUZQFDMBTTJOTUBODFT w compareDBOBMTPCFFYUFOTJPONFUIPE w *OUIJTDBTF compareTIPVMECFJNQMFNFOUFEJOJOTUBODF EFDMBSBUJPO ܕΫϥε͕ཁٻ͢Δϝιου͕֦ுϝιουͰ΋ྑ͍ trait

    Comparator[T] { def (a: T) compare (b: T): Int def (a: T) > (b: T): Boolean = a.compare(b) > 0 } object Comparators { delegate for Comparator[Int] { def (a: Int) compare (b: Int): Int = a - b } }
  46. ܕΫϥε੍໿Λ࣋ͭΠϯελϯεએݴ *OTUBODFEFDMBSBUJPOXJUIUZQFDMBTTDPOTUSBJOU w “delegate for”EFDMBSBUJPODBOUBLF“given”DMBVTF w QBSBNFUFSOBNFJO“given”DMBVTFJTPQUJPOBM 4DBMBͱҟͳΓɺΠϯελϯεએݴ͸ৗʹEFMFHBUFGPS object Comparators

    { delegate TupleComparator [T1, T2] for Comparator[(T1, T2)] given Comparator[T1], Comparator[T2] { def (a: (T1, T2)) compare (b: (T1, T2)): Int = { val res1 = a._1.compare(b._1) if (res1 == 0) a._2.compare(b._2) else res1 } } }
  47. ·ͱΊ $PODMVTJPO 4DBMBͱ4DBMB͸ܕΫϥεͷॻ͖ํ͕େ͖͘ҧ͏ 4DBMBͷํ͕Θ͔Γ΍͍͢ typeclass declaration instance declaration typeclass constraint

    extension methods import instance declaration Scala2 trait implicit object/val/def implicit parameter implicit 
 class/def import Scala3 trait delegate for given extension methods import delegate