SlideShare a Scribd company logo
HOW TO GET ALONG WITH IMPLICIT
Taisuke Oe / @OE_uia
WHO AM I?
Taisuke Oe @OE_uia
A gleaner as:
- the chairperson in ScalaMatsuri
- VPoE in F-CODE, INC.
Sometimes, a glean instructor as:
- a technical advisor in Septeni Original, Inc.
いろんな組織で落ち穂拾いしてます
RECAP: WHAT IS IMPLICIT?
TWO TYPES OF IMPLICIT
Implicit parameter
Implicit conversion
SIMPLE IMPLICIT PARAMETER EXAMPLE
from Scala Standard Library:
trait Seq[A]{
def sorted[B >: A](implicit ord: math.Ordering[B]): Seq[A]
}
scala> Seq(2,1,3).sorted
//Seq(1,2,3)
ord: math.Ordering[B] argument is passed implicitly.
Seq#sorted は最も単純な暗黙の引数の例
SIMPLE IMPLICIT CONVERSION EXAMPLE
from Scala Standard Library:
import scala.collection.JavaConverters._
val jList:java.util.List[Int] = List(1,2,3).asJava
IMPLICIT
Why is Implicit regarded as dif cult?
なぜ暗黙は難しいと思われがちなんだろう?
WHY?
- `Implicit` is NOT really explicit about what happens.
You'll need some tools to gure it out.
- `Implicit` scope is a bit complicated.
Scaladoc cannot explain `Implicit` values in its scope.
- `Implicit` is often designed to be induced.
暗黙の難しさ。
1) 何が起きているか明示されない 2) スコープがちょっと複雑 3)しばしば導出を前提にデザインされる
AGAIN, SIMPLE IMPLICIT PARAMETER EXAMPLE
Seq(2,1,3).sorted
//Seq(1,2,3)
Check with "-Xprint:typer" scalac option.
先程の例に戻り、どのように暗黙の値が解決されているか調べてみましょう。
-XPRINT:TYPER
DEMO
-XPRINT:TYPER
Sample.scala
object Main{
Seq(2,1,3).sorted
}
$ scalac -Xprint:typer Sample.scala
[[syntax trees at end of typer]] // Sample.scala
package <empty> {
object Main extends scala.AnyRef {
def <init>(): Main.type = {
Main.super.<init>();
()
};
scala.collection.Seq.apply[Int](2, 1, 3).sorted[Int](math.this.Ordering
}
}
`-Xprint:typer` allows us to gure out how implicit is resolved.
どのように暗黙の値の解決されてるか、分かる。
FOR MORE COMPLICATED PROJECTS
- Import working examples to IntelliJ IDEA
- Use `Implicit Parameter` function (Implicit Analyzer)
複雑なプロジェクトには、IntelliJ IDEAでSImplicit Parameterを調べようという機能がオススメ。
IMPLICIT ANALYZER
DEMO
HOW ABOUT IMPLICIT CONVERSION CASE?
- As long as it's implemented in *Enrich my library pattern*, easy stuff.
- *Enrich my library pattern* - Convert to a wrapper class with a new method you want.
- *Go to Declarations* in IntelliJ, or something similar in your editor.
Enrich my libraryパターンなら簡単に定義場所に飛べる
HOW ABOUT IMPLICIT CONVERSION CASE?
- Non *Enrich my library pattern* implicit conversion is not recommended.
- Ah, good luck.
- You can use `Implicit Conversions` in IntelliJ,
Enrich my libraryパターンじゃない暗黙の型変換は、そもそも非推奨
TIPS 1
Find working examples and analyze them.
動いているコードを探すのが、暗黙解決を理解するのに手っ取り早いでしょう
FIND WORKING EXAMPLES
Source codes that can compile.
- project codes by your team.
- Getting Started
- examples in OSS project repositories
- test codes
サンプルコードを見つける場所候補。
WHERE DOES ORDERING[INT] INSTANCE
COME FROM?
package scala.math
object Ordering {
trait IntOrdering extends Ordering[Int] {
def compare(x: Int, y: Int) = java.lang.Integer.compare(x, y)
}
implicit object Int extends IntOrdering
}
scala.math.Ordering.Int is in its Implicit scope.
scala.math.Ordering.Intが暗黙のスコープ内に定義されているので、先程の例はコンパイルできるのです。
TIPS 2
Get familiar with common ways to include implicit values in the scope.
暗黙の値をスコープに加える代表的な方法を理解しよう。
IMPLICIT SCOPE?
Explicit imports / de nition
Comapnion modules of associated types.
EXPLICIT IMPORTS / DEFINITION
import scala.concurrent._
import ExecutionContext.Implicits.global
Future(1+2)
Import values de ned in a certain object. (Its name is sometimes obviouse like *Implicits*)
暗黙の値が定義されているobjectの値をimportしよう。Implicitsみたいな分かりやすい名前が推奨
COMAPNION MODULES OF ASSOCIATED TYPES
Quotes from Scala Language Speci cation 7.2 Implicit parameter
The implicit scope of a type T consists of all companion modules of classes
The parts of a type T are:
if T is a compound type T1 with …… with Tn, the union of the parts of T1,
if T is a parameterized type S[T1,…,Tn], the union of the parts of SS and
if T is a singleton type p.type, the parts of the type of p;
if T is a type projection S#U, the parts of S as well as T itself;
if T is a type alias, the parts of its expansion;
if T is an abstract type, the parts of its upper bound;
if T denotes an implicit conversion to a type with a method with argument
the parts of quantified (existential or universal) and annotated types are define
in all other cases, just T itself.
暗黙のスコープは、Scala言語仕様にまとまっています。
COMPANION OBJECTS OF ... WHAT?
You don't need to understand *an associated type* 100%.
Let's get along with common / ordinal patterns, one by one.
「関連のある型」のパターンを一緒に見てみよう
FREQUENTLY USED IMPLICIT SCOPES
PARAMETERIZED TYPE
trait A
object A {
implicit val ba:B[A] = new B[A]{}
}
trait B[T]
object B {
implicit val bc:B[C] = new B[C]{}
}
trait C
implicitly[B[A]]
implicitly[B[C]]
B[A]は、B,A両方のコンパニオンオブジェクト
SUPER TYPE
trait A
trait B extends A
object A{
implicit val b:B = new B{}
}
implicitly[B]
型Bのスーパー型Aのコンパニオンオブジェクトもスコープ内
PACKAGE OBJECT
package O
trait A
package object P{
implicit val a:A = new A{}
}
package P{
object B {implicitly[A]}
}
FOR REFERENCE.
TYPE A
trait A
object A{
implicit val a:A = new A{}
}
implicitly[A]
型A自身のコンパニオンオブジェクト
COMPOUND TYPE
trait A
object A{
implicit val ac:A with C = new A with C{}
}
trait C
implicitly[A with C]
A and C.
合成型A with Cは、AとC両方のコンパニオンオブジェクト。
TYPE ALIAS
trait A
object A{
implicit val a:A = new A{}
}
type D = A
implicitly[D]
ABSTRACT TYPE WITH UPPER BOUND
trait A
trait ASub extends A
trait B {type D <: A}
object A extends B{
type D = ASub
implicit val a:ASub = new ASub{}
}
implicitly[A.D]
IMPLICIT CONVERSION
trait A
object A {
implicit def f(a:A):B = new B{}
implicit def g(b:B):A = new A{}
}
trait B
val a:A = new B{}
//NG
//val b:B = new A{}
暗黙の型変換の、引数の型A
IMPLICIT CLASS
trait A
object A {
implicit class B(a:A)
}
implicitly[A => A.B]
val b:A.B = new A{}
TYPE PROJECTION
trait A { trait E }
object A {
private val a:A = new A{}
implicit val e:a.E = new a.E{}
}
implicitly[A#E]
SINGLETON TYPE
object A {
implicit val a:A.type = this
}
implicitly[A.type]
Associated type of A.type is A.
WHERE DID WE FIND ORDERING[INT]?
package scala.math
object Ordering {
trait IntOrdering extends Ordering[Int] {
def compare(x: Int, y: Int) = java.lang.Integer.compare(x, y)
}
implicit object Int extends IntOrdering
}
In companion object of `Ordering`.
Orderingのコンパニオンオブジェクトに定義していました。
DEFINE YOUR OWN DATA TYPE.
case class User(name:String)
scala> Seq(User("B"),User("A")).sorted
//ERROR since `Ordering[User]` instance is NOT defined within Implicit scope.
Seq[User] can't be sorted since there is no Ordering[User] instance.
User型を定義しただけだと、Seq[User]をsortedすることはできません。
DEFINE ORDERING[USER] INSTANCE.
case class User(name:String)
object User{
//Get an Ordering[User] from Ordering[User]
implicit val ordering:Ordering[User] = Ordering.by(_.name)
}
scala> Seq(User("B"),User("A")).sorted
// Seq(User(A), User(B))
Ordering[User]型を得ることで、Seq[User]をsortedすることができました。
De ne Ordering[User] instance in companion object of `User`.
Ordering[User]型を得ることで、Seq[User]をsortedすることができました。
HOW DID WE DEFINE ORDERING[USER] INSTANCE?
implicit val ordering:Ordering[User] = Ordering.by(_.name)
object Ordering{
def by[T, S](f: (T) ⇒ S)(implicit ord: Ordering[S]): Ordering[T]
}
trait Ordering[T]{
def on[U](f: (U) ⇒ T): Ordering[U]
}
Watch out: direction of argument functions
Ordering型のインスタンスは、既存のOrdering型から作ることができる。
WAYS TO GET FROM EXISTING IMPLICIT VALUES
There are so many ways to do so:
Remember map , contramap and imap .
MAP AND CONTRAMAP
trait SerializedFormat
trait Reads[T]{
def read(arg:SerializedFormat):T
def map[U](f:T => U):Reads[U]
}
trait Writes[T]{
def writes(t:T):SerializedFormat
def contramap[U](f: U => T):Writes[U]
}
`T` is in :
return value position -> `map`
argument position -> `contramap`
型パラメータが戻り値のポジションの場合は`map`, 引数のポジションの場合は `contramap`
EXAMPLE: ORDERING[T]
package scala.math
trait Ordering[T] {
//abstract method
def compare(x: T, y: T): Int
/* ... */
}
Since `T` is in argument position, `Ordering.by` and `Ordering#on` are the same as `contramap`.
Orderingの場合も例外ではなく、Tが引数ポジションだから`contramap` 相当のメソッド。
OTHER EXAMPLES OF MAP AND CONTRAMAP
play-json: Reads[T], Writes[T]
ScalikeJDBC: TypeBinder[T], ParameterBinderFactory[T]
IMAP
trait Semigroup[T]{
//Like a standard Semigroup.
def append(x:T,y:T):T
//Like an InvariantFunctor
def imap[A](f: T => A)(g: A => T): Semigroup[A]
}
`T` is in both of return value and argument position -> `imap`
もしTが引数と戻り値の両方のポジションに出てくるなら、それは `imap` の出番だ
OTHER EXAMPLES OF IMAP
ScalikeJDBC: Binders[T] as xmap
DERIVING (TYPECLASS) INSTANCES FROM OTHERS
play-json uses macro to derive instances.
e.g. Json.reads[T], Json.writes[T]
shapeless uses HList to derive instances.
e.g. shapeless-contrib
AUTOMATIC DERIVATION EXAMPLE
case class Value(i:Int)
import MonoidSyntax._
import Monoid.typeClass._
Value(10) |+| Value(12)
//Value(22)
TIPS 3
Know basic ways to modify existing implicit values.
(Brand-new de nition would be second option.)
できるだけ既存の値を加工しよう
CONCLUSION
- `Implicit` is NOT really explicit about what happens.
=> Find working examples, and analyze them.
- `Implicit` scope is a bit complicated.
=> Get familiar with common ways to include implicit values in the scope.
- `Implicit` is often designed to be induced.
=> Know basic ways to modify existing implicit values.
暗黙とうまく付き合うための第一歩として、紹介したようなポイントを抑えましょう

More Related Content

PPTX
Clean code slide
KEY
Clean code and Code Smells
PPTX
pointer, virtual function and polymorphism
PDF
Clean coding-practices
PDF
7 rules of simple and maintainable code
PPTX
Pointers, virtual function and polymorphism
PPTX
Pointers,virtual functions and polymorphism cpp
PDF
Javaz. Functional design in Java 8.
Clean code slide
Clean code and Code Smells
pointer, virtual function and polymorphism
Clean coding-practices
7 rules of simple and maintainable code
Pointers, virtual function and polymorphism
Pointers,virtual functions and polymorphism cpp
Javaz. Functional design in Java 8.

What's hot (20)

PPTX
Introduction to Client-Side Javascript
PDF
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
PPTX
07. Virtual Functions
PPTX
Functions in c++
PPTX
Functions in c++
PDF
Clean code
PPTX
Functional programming
PPT
pointer, structure ,union and intro to file handling
PPTX
Clean code
PPT
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
PDF
L2
PDF
Functional programming ii
PPT
PHP 5.3 Part 2 - Lambda Functions & Closures
PPT
Csharp In Detail Part2
PDF
Functions in C++
PPT
pointer, structure ,union and intro to file handling
PDF
Let's refine your Scala Code
PPTX
TEMPLATES IN JAVA
PDF
Practical Functional Programming Presentation by Bogdan Hodorog
PPTX
Function class in c++
Introduction to Client-Side Javascript
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
07. Virtual Functions
Functions in c++
Functions in c++
Clean code
Functional programming
pointer, structure ,union and intro to file handling
Clean code
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
L2
Functional programming ii
PHP 5.3 Part 2 - Lambda Functions & Closures
Csharp In Detail Part2
Functions in C++
pointer, structure ,union and intro to file handling
Let's refine your Scala Code
TEMPLATES IN JAVA
Practical Functional Programming Presentation by Bogdan Hodorog
Function class in c++
Ad

More from Taisuke Oe (11)

PDF
プレScalaMatsuri2019「スピーカー入門」
PDF
How to start functional programming (in Scala): Day1
PDF
Monix Taskが便利だという話
PDF
What Dotty fixes @ Scala関西サミット
PDF
Real World Android Akka - 日本語版
PDF
AuxパターンをDottyで解決する
PDF
Real World Android Akka
PDF
Real world android akka
PDF
多相な関数の定義から学ぶ、型クラスデザインパターン
PDF
Android BLEのつらみを予防するTips
PDF
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
プレScalaMatsuri2019「スピーカー入門」
How to start functional programming (in Scala): Day1
Monix Taskが便利だという話
What Dotty fixes @ Scala関西サミット
Real World Android Akka - 日本語版
AuxパターンをDottyで解決する
Real World Android Akka
Real world android akka
多相な関数の定義から学ぶ、型クラスデザインパターン
Android BLEのつらみを予防するTips
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
Ad

Recently uploaded (20)

PPTX
history of c programming in notes for students .pptx
PDF
AI in Product Development-omnex systems
PDF
Nekopoi APK 2025 free lastest update
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
Online Work Permit System for Fast Permit Processing
PPTX
Transform Your Business with a Software ERP System
PPT
Introduction Database Management System for Course Database
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PPTX
Introduction to Artificial Intelligence
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
medical staffing services at VALiNTRY
history of c programming in notes for students .pptx
AI in Product Development-omnex systems
Nekopoi APK 2025 free lastest update
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Online Work Permit System for Fast Permit Processing
Transform Your Business with a Software ERP System
Introduction Database Management System for Course Database
How to Migrate SBCGlobal Email to Yahoo Easily
Wondershare Filmora 15 Crack With Activation Key [2025
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Introduction to Artificial Intelligence
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
Design an Analysis of Algorithms II-SECS-1021-03
Operating system designcfffgfgggggggvggggggggg
PTS Company Brochure 2025 (1).pdf.......
Navsoft: AI-Powered Business Solutions & Custom Software Development
Odoo Companies in India – Driving Business Transformation.pdf
medical staffing services at VALiNTRY

How to get along with implicits

  • 1. HOW TO GET ALONG WITH IMPLICIT Taisuke Oe / @OE_uia
  • 2. WHO AM I? Taisuke Oe @OE_uia A gleaner as: - the chairperson in ScalaMatsuri - VPoE in F-CODE, INC. Sometimes, a glean instructor as: - a technical advisor in Septeni Original, Inc. いろんな組織で落ち穂拾いしてます
  • 3. RECAP: WHAT IS IMPLICIT?
  • 4. TWO TYPES OF IMPLICIT Implicit parameter Implicit conversion
  • 5. SIMPLE IMPLICIT PARAMETER EXAMPLE from Scala Standard Library: trait Seq[A]{ def sorted[B >: A](implicit ord: math.Ordering[B]): Seq[A] } scala> Seq(2,1,3).sorted //Seq(1,2,3) ord: math.Ordering[B] argument is passed implicitly. Seq#sorted は最も単純な暗黙の引数の例
  • 6. SIMPLE IMPLICIT CONVERSION EXAMPLE from Scala Standard Library: import scala.collection.JavaConverters._ val jList:java.util.List[Int] = List(1,2,3).asJava
  • 7. IMPLICIT Why is Implicit regarded as dif cult? なぜ暗黙は難しいと思われがちなんだろう?
  • 8. WHY? - `Implicit` is NOT really explicit about what happens. You'll need some tools to gure it out. - `Implicit` scope is a bit complicated. Scaladoc cannot explain `Implicit` values in its scope. - `Implicit` is often designed to be induced. 暗黙の難しさ。 1) 何が起きているか明示されない 2) スコープがちょっと複雑 3)しばしば導出を前提にデザインされる
  • 9. AGAIN, SIMPLE IMPLICIT PARAMETER EXAMPLE Seq(2,1,3).sorted //Seq(1,2,3) Check with "-Xprint:typer" scalac option. 先程の例に戻り、どのように暗黙の値が解決されているか調べてみましょう。
  • 12. $ scalac -Xprint:typer Sample.scala [[syntax trees at end of typer]] // Sample.scala package <empty> { object Main extends scala.AnyRef { def <init>(): Main.type = { Main.super.<init>(); () }; scala.collection.Seq.apply[Int](2, 1, 3).sorted[Int](math.this.Ordering } } `-Xprint:typer` allows us to gure out how implicit is resolved. どのように暗黙の値の解決されてるか、分かる。
  • 13. FOR MORE COMPLICATED PROJECTS - Import working examples to IntelliJ IDEA - Use `Implicit Parameter` function (Implicit Analyzer) 複雑なプロジェクトには、IntelliJ IDEAでSImplicit Parameterを調べようという機能がオススメ。
  • 15. HOW ABOUT IMPLICIT CONVERSION CASE? - As long as it's implemented in *Enrich my library pattern*, easy stuff. - *Enrich my library pattern* - Convert to a wrapper class with a new method you want. - *Go to Declarations* in IntelliJ, or something similar in your editor. Enrich my libraryパターンなら簡単に定義場所に飛べる
  • 16. HOW ABOUT IMPLICIT CONVERSION CASE? - Non *Enrich my library pattern* implicit conversion is not recommended. - Ah, good luck. - You can use `Implicit Conversions` in IntelliJ, Enrich my libraryパターンじゃない暗黙の型変換は、そもそも非推奨
  • 17. TIPS 1 Find working examples and analyze them. 動いているコードを探すのが、暗黙解決を理解するのに手っ取り早いでしょう
  • 18. FIND WORKING EXAMPLES Source codes that can compile. - project codes by your team. - Getting Started - examples in OSS project repositories - test codes サンプルコードを見つける場所候補。
  • 19. WHERE DOES ORDERING[INT] INSTANCE COME FROM? package scala.math object Ordering { trait IntOrdering extends Ordering[Int] { def compare(x: Int, y: Int) = java.lang.Integer.compare(x, y) } implicit object Int extends IntOrdering } scala.math.Ordering.Int is in its Implicit scope. scala.math.Ordering.Intが暗黙のスコープ内に定義されているので、先程の例はコンパイルできるのです。
  • 20. TIPS 2 Get familiar with common ways to include implicit values in the scope. 暗黙の値をスコープに加える代表的な方法を理解しよう。
  • 21. IMPLICIT SCOPE? Explicit imports / de nition Comapnion modules of associated types.
  • 22. EXPLICIT IMPORTS / DEFINITION import scala.concurrent._ import ExecutionContext.Implicits.global Future(1+2) Import values de ned in a certain object. (Its name is sometimes obviouse like *Implicits*) 暗黙の値が定義されているobjectの値をimportしよう。Implicitsみたいな分かりやすい名前が推奨
  • 23. COMAPNION MODULES OF ASSOCIATED TYPES Quotes from Scala Language Speci cation 7.2 Implicit parameter The implicit scope of a type T consists of all companion modules of classes The parts of a type T are: if T is a compound type T1 with …… with Tn, the union of the parts of T1, if T is a parameterized type S[T1,…,Tn], the union of the parts of SS and if T is a singleton type p.type, the parts of the type of p; if T is a type projection S#U, the parts of S as well as T itself; if T is a type alias, the parts of its expansion; if T is an abstract type, the parts of its upper bound; if T denotes an implicit conversion to a type with a method with argument the parts of quantified (existential or universal) and annotated types are define in all other cases, just T itself. 暗黙のスコープは、Scala言語仕様にまとまっています。
  • 24. COMPANION OBJECTS OF ... WHAT? You don't need to understand *an associated type* 100%. Let's get along with common / ordinal patterns, one by one. 「関連のある型」のパターンを一緒に見てみよう
  • 26. PARAMETERIZED TYPE trait A object A { implicit val ba:B[A] = new B[A]{} } trait B[T] object B { implicit val bc:B[C] = new B[C]{} } trait C implicitly[B[A]] implicitly[B[C]] B[A]は、B,A両方のコンパニオンオブジェクト
  • 27. SUPER TYPE trait A trait B extends A object A{ implicit val b:B = new B{} } implicitly[B] 型Bのスーパー型Aのコンパニオンオブジェクトもスコープ内
  • 28. PACKAGE OBJECT package O trait A package object P{ implicit val a:A = new A{} } package P{ object B {implicitly[A]} }
  • 30. TYPE A trait A object A{ implicit val a:A = new A{} } implicitly[A] 型A自身のコンパニオンオブジェクト
  • 31. COMPOUND TYPE trait A object A{ implicit val ac:A with C = new A with C{} } trait C implicitly[A with C] A and C. 合成型A with Cは、AとC両方のコンパニオンオブジェクト。
  • 32. TYPE ALIAS trait A object A{ implicit val a:A = new A{} } type D = A implicitly[D]
  • 33. ABSTRACT TYPE WITH UPPER BOUND trait A trait ASub extends A trait B {type D <: A} object A extends B{ type D = ASub implicit val a:ASub = new ASub{} } implicitly[A.D]
  • 34. IMPLICIT CONVERSION trait A object A { implicit def f(a:A):B = new B{} implicit def g(b:B):A = new A{} } trait B val a:A = new B{} //NG //val b:B = new A{} 暗黙の型変換の、引数の型A
  • 35. IMPLICIT CLASS trait A object A { implicit class B(a:A) } implicitly[A => A.B] val b:A.B = new A{}
  • 36. TYPE PROJECTION trait A { trait E } object A { private val a:A = new A{} implicit val e:a.E = new a.E{} } implicitly[A#E]
  • 37. SINGLETON TYPE object A { implicit val a:A.type = this } implicitly[A.type] Associated type of A.type is A.
  • 38. WHERE DID WE FIND ORDERING[INT]? package scala.math object Ordering { trait IntOrdering extends Ordering[Int] { def compare(x: Int, y: Int) = java.lang.Integer.compare(x, y) } implicit object Int extends IntOrdering } In companion object of `Ordering`. Orderingのコンパニオンオブジェクトに定義していました。
  • 39. DEFINE YOUR OWN DATA TYPE. case class User(name:String) scala> Seq(User("B"),User("A")).sorted //ERROR since `Ordering[User]` instance is NOT defined within Implicit scope. Seq[User] can't be sorted since there is no Ordering[User] instance. User型を定義しただけだと、Seq[User]をsortedすることはできません。
  • 40. DEFINE ORDERING[USER] INSTANCE. case class User(name:String) object User{ //Get an Ordering[User] from Ordering[User] implicit val ordering:Ordering[User] = Ordering.by(_.name) } scala> Seq(User("B"),User("A")).sorted // Seq(User(A), User(B)) Ordering[User]型を得ることで、Seq[User]をsortedすることができました。 De ne Ordering[User] instance in companion object of `User`. Ordering[User]型を得ることで、Seq[User]をsortedすることができました。
  • 41. HOW DID WE DEFINE ORDERING[USER] INSTANCE? implicit val ordering:Ordering[User] = Ordering.by(_.name) object Ordering{ def by[T, S](f: (T) ⇒ S)(implicit ord: Ordering[S]): Ordering[T] } trait Ordering[T]{ def on[U](f: (U) ⇒ T): Ordering[U] } Watch out: direction of argument functions Ordering型のインスタンスは、既存のOrdering型から作ることができる。
  • 42. WAYS TO GET FROM EXISTING IMPLICIT VALUES There are so many ways to do so: Remember map , contramap and imap .
  • 43. MAP AND CONTRAMAP trait SerializedFormat trait Reads[T]{ def read(arg:SerializedFormat):T def map[U](f:T => U):Reads[U] } trait Writes[T]{ def writes(t:T):SerializedFormat def contramap[U](f: U => T):Writes[U] } `T` is in : return value position -> `map` argument position -> `contramap` 型パラメータが戻り値のポジションの場合は`map`, 引数のポジションの場合は `contramap`
  • 44. EXAMPLE: ORDERING[T] package scala.math trait Ordering[T] { //abstract method def compare(x: T, y: T): Int /* ... */ } Since `T` is in argument position, `Ordering.by` and `Ordering#on` are the same as `contramap`. Orderingの場合も例外ではなく、Tが引数ポジションだから`contramap` 相当のメソッド。
  • 45. OTHER EXAMPLES OF MAP AND CONTRAMAP play-json: Reads[T], Writes[T] ScalikeJDBC: TypeBinder[T], ParameterBinderFactory[T]
  • 46. IMAP trait Semigroup[T]{ //Like a standard Semigroup. def append(x:T,y:T):T //Like an InvariantFunctor def imap[A](f: T => A)(g: A => T): Semigroup[A] } `T` is in both of return value and argument position -> `imap` もしTが引数と戻り値の両方のポジションに出てくるなら、それは `imap` の出番だ
  • 47. OTHER EXAMPLES OF IMAP ScalikeJDBC: Binders[T] as xmap
  • 48. DERIVING (TYPECLASS) INSTANCES FROM OTHERS play-json uses macro to derive instances. e.g. Json.reads[T], Json.writes[T] shapeless uses HList to derive instances. e.g. shapeless-contrib
  • 49. AUTOMATIC DERIVATION EXAMPLE case class Value(i:Int) import MonoidSyntax._ import Monoid.typeClass._ Value(10) |+| Value(12) //Value(22)
  • 50. TIPS 3 Know basic ways to modify existing implicit values. (Brand-new de nition would be second option.) できるだけ既存の値を加工しよう
  • 51. CONCLUSION - `Implicit` is NOT really explicit about what happens. => Find working examples, and analyze them. - `Implicit` scope is a bit complicated. => Get familiar with common ways to include implicit values in the scope. - `Implicit` is often designed to be induced. => Know basic ways to modify existing implicit values. 暗黙とうまく付き合うための第一歩として、紹介したようなポイントを抑えましょう