Your SlideShare is downloading. ×
0
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Implicit Explicit Scala
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Implicit Explicit Scala

2,859

Published on

Scalaのimplicit parameter入門的な何かです。

Scalaのimplicit parameter入門的な何かです。

Published in: Technology
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,859
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
11
Comments
0
Likes
3
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Implicit Explicit Scala 水島 宏太 (@kmizu)
  • 2. 自己紹介
  • 3. の前にお約束
  • 4. JIT(Just In Tsukkomi)歓迎
  • 5. @kmizu http://twitter.com/kmizu @ktmizushima (English) http://twitter.com/ktmizushima id:kmizushimahttp://d.hatena.ne.jp/kmizushima Scala辻斬り ヒーラー
  • 6. Continuation Workshop 2011 (2011/09/24)限定継続の人(Tiark Rompf)が来てた あ、ありのまま(ry
  • 7. ちなみにこの自己紹介は(ry
  • 8. 今回説明すること
  • 9. その前にQuiz * 3
  • 10. ルール:-Xprint:typer禁止
  • 11. Q.1 A1-A3, B1-B3 を埋めてくださいval m = Map("A" -> 1, "B" -> 2)m.map{case (x, y) => (y, x)}m.map{case (x, y) => x}m.map[A1, A2]({case (x, y) => (y, x) })(?:A3)m.map[B1, B2]{case (x, y) => x })(?:B3)
  • 12. A.1val m = Map("A" -> 1, "B" -> 2)m.map{case (x, y) => (y, x)}m.map{case (x, y) => x}m.map[(Int, String), Map[Int, String]]{ case (x, y) => (y, x) }(?:CanBuildFrom[Map[String, Int], String, Map[Int, String])m.map[String, Iterable[String]]({ case (x, y) => x })(?:CanBuildFrom[Map[String, Int], String, Iterable[String]]
  • 13. Why ?
  • 14. Q.2 A1, A2, B1, B2 を埋めてくださいval l1 = List(1, 2, 3)val l2 = List(1.5, 2.5, 3.5)l1.suml2.suml1.sum[A1](?:A2)l2.sum[B2](?:B2)
  • 15. A.2val l1 = List(1, 2, 3)val l2 = List(1.5, 2.5, 3.5)l1.suml2.suml1.sum[Int](?:Numeric[Int])l2.sum[Double](?:Numeric[Double])
  • 16. Why ?
  • 17. Q.3 A1-A3, B1-B3 を埋めてくださいval l1 = List("A" -> 1, "B" -> 2)val l2 = List(1, 2, 3)l1.toMapl2.toMapl1.toMap[A1, A2](?:A3)l2.toMap[B1, B2](?:B3)
  • 18. A.3val l1 = List("A" -> 1, "B" -> 2)val l2 = List(1, 2, 3)l1.toMapl2.toMapl1.toMap[String, Int](?: (String, Int) <:< (String, Int))l2.toMap[B1, B2](?:B3)→ error: Cannot prove that Int <:< (T, U).
  • 19. Why ?
  • 20. 3つに共通するもの
  • 21. それは
  • 22. Implicit Parameter
  • 23. Implicit Parameter
  • 24. 最も誤解されてきた機能
  • 25. 実はとても強力な機能
  • 26. implicit parameter=省略可能引数
  • 27. とりあえず
  • 28. implicit parameter
  • 29. が今回のメイン
  • 30. A.1~A.3の意味がわかる ようになる(はず)
  • 31. 基本
  • 32. def hoge(implicit x: Int) = x + 3implicit val INT: Int = 3println(hoge) → println(hoge(INT)) → 6
  • 33. 間違いではないが
  • 34. 全然嬉しくない
  • 35. 基本
  • 36. trait Addible[A] { def plus(x: A, y: A): A def zero: A}implicit object IntAddible extends Addible[Int] { def plus(x: Int, y: Int): Int = x + y def zero: Int = 0}def sum[A](nums: List[A])(implicit addible: Addible[A]): A = { nums.foldLeft(addible.zero)((x, y) => addible.plus(x, y))}println(sum(List(1, 2, 3, 4, 5)))→ println(sum(List(1, 2, 3, 4, 5))(IntAddible))
  • 37. implicit宣言された型に適合する implicitな値を拾ってくれる
  • 38. implicit探索規則
  • 39. 基本:静的スコープで決まる
  • 40. メソッド呼び出し時に「直接参 照可能な」implicitな値が対象
  • 41. 「直接参照可能な」の意味1. 同一スコープにimplicitな値が定義されている2. importによってimplicitな値が導入されている
  • 42. 例外規則
  • 43. implicit parameterの型に「関連付けられ たクラス/トレイト」のコンパニオンオ ブジェクトも探索対象
  • 44. 「関連付けられたクラス/トレイト」
  • 45. trait G[A, B, C] の場合:G, A, B, C のコンパニオンオブジェクトを探索
  • 46. trait Addible[A] { def plus(x: A, y: A): A def zero: A}object Addible { //companion object implicit object IntAddible extends Addible[Int] { def plus(x: Int, y: Int): Int = x + y def zero: Int = 0 }}def sum[A](nums: List[A])(implicit addible: Addible[A]): A = { nums.foldLeft(addible.zero)((x, y) => addible.plus(x, y))}println(sum(List(1, 2, 3, 4, 5)))→ println(sum(List(1, 2, 3, 4, 5))(IntAddible)) // OK
  • 47. デフォルトで探索対象にして欲しいimplicitな値をコンパニオンオブジェクト に入れると便利
  • 48. 何が嬉しい?
  • 49. Doubleもsumしたくなった
  • 50. implicit object DoubleAddible extends Addible[Int] { def plus(x: Double, y: Double): Double = x + y def zero: Double = 0.0}println(sum(List(1.0, 2.0, 3.0)))→ println(sum(List(1.0, 2.0, 3.0))(DoubleAddible))
  • 51. 元のデータ型に変更を加えずに
  • 52. データ型の性質を新しく定義
  • 53. 特殊:implicit推論規則
  • 54. implicitな値から型パラメータを 「逆向きに」推論可能
  • 55. Scala 2.8で導入
  • 56. implicit val tupleA: (Int, String) = (1, "A")implicit val tupleB: (Double, String) = (1.5, "B")def useImplicitTuple2[A, B](value: A)(implicit tuple: (A, B)): B = { tuple._2}println(useImplicitTuple2(100)) // Aprintln(useImplicitTuple2(1.5)) // B
  • 57. Aに応じて推論されるBが変わる
  • 58. 2.8コレクションには不可欠
  • 59. A.1 ~ A.3の定義をもう一度見てみる
  • 60. A.1val m = Map("A" -> 1, "B" -> 2)// def map [B, That] (f: ((A, B)) ⇒ B)(implicit bf: CanBuildFrom[Map[A, B], B, That]): Thatm.map{case (x, y) => (y, x)}m.map{case (x, y) => x}m.map[(Int, String), Map[Int, String]]{ case (x, y) => (y, x) }(?:CanBuildFrom[Map[String, Int], String, Map[Int, String])m.map[String, Iterable[String]]({ case (x, y) => x })(?:CanBuildFrom[Map[Int, String], String, Iterable[String]])
  • 61. 引数の型情報から順方向に推論 したのではThatはわからないimplicit推論規則による解決
  • 62. scala.collection.immutable.Map のコンパニオンオブジェクト
  • 63. package scala.collectionpackage immutableobject Map ... { .. //Coll = Map[_, _] implicit def canBuildFrom[A, B]: CanBuildFrom[Coll, (A, B), Map[A, B]] = new MapCanBuildFrom[A, B]}
  • 64. (1) 任意の型A, B について CanBuildFrom[Map[_, _], (A, B), Map[A, B]]型のimplicitな値を生成可能
  • 65. scala.collection.Iterableのコンパニオンオブジェクト
  • 66. package scala.collection...object Iterable ... { .. //Coll = Iterable[A] implicit def canBuildFrom[A]: CanBuildFrom[Coll, (A), Iterable[A]] = new GenericCanBuildFrom[A]}
  • 67. (2) 任意の型A, B について CanBuildFrom[Iterable[_, _], (A), Iterable[A]]型のimplicitな値を生成可能
  • 68. 適用優先度: (1) > (2)
  • 69. (1)が適合していなくても (2)が適合すればOK
  • 70. A.2val l1 = List(1, 2, 3)val l2 = List(1.5, 2.5, 3.5)l1.suml2.sum// def sum [B >: A] (implicit num: Numeric[B]): Bl1.sum[Int](?:Numeric[Int])l2.sum[Double](?:Numeric[Double])
  • 71. package scala.math...object Numeric { trait IntIsIntegral extends Integral[Int] { def plus(x: Int, y: Int): Int = x + y def minus(x: Int, y: Int): Int = x - y def times(x: Int, y: Int): Int = x * y def quot(x: Int, y: Int): Int = x / y def rem(x: Int, y: Int): Int = x % y def negate(x: Int): Int = -x def fromInt(x: Int): Int = x def toInt(x: Int): Int = x.toInt def toLong(x: Int): Long = x def toFloat(x: Int): Float = x def toDouble(x: Int): Double = x } .. // Integeral[T] <: Numeric[T] なので、 Numeric[Int]のimplicitな値も同時に定義 // していることになる implicit object IntIsIntegral extends IntIsIntegral with Ordering.IntOrdering}
  • 72. A.3val l1 = List("A" -> 1, "B" -> 2)val l2 = List(1, 2, 3)l1.toMapl2.toMap 名状し難い型l1.toMap[String, Int](?: (String, Int) <:< (String, Int))l2.toMap[B1, B2](?:B3)→ error: Cannot prove that Int <:< (T, U).
  • 73. 答えはPredefの中に
  • 74. package scala.math...object Predef ... { @implicitNotFound(msg = "Cannot prove that ${From} <:< ${To}.") sealed abstract class <:<[-From, +To] extends (From => To) with Serializable 名状し難い型の定義 private[this] final val singleton_<:< = new <:<[Any,Any] { def apply(x: Any): Any = x } // not in the <:< companion object because it is also // intended to subsume identity (which is no longer implicit) implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]}
  • 75. ポイント
  • 76. sealed abstract class <:<[-From, +To]implicit def conforms[A]: A <:< A = singleton_<:<.asInstanceOf[A <:< A]
  • 77. 任意の型AについてA <: A 型のimplicitな値を生成 可能(多相的なimplicit)
  • 78. 名状し難い <:< の左辺:contravariant (-) 右辺: covariant(+)
  • 79. def fun[A, B](a: A, b: B)(implicit ev: A <:< B)
  • 80. A = Int, B = Any つまり A <: B のとき(Int <:< Any) なimplicitな値が必要
  • 81. (Int <:< Int) <: (Int <:< Any) なので (<:< の右辺はcovariant)conforms[Int]: Int <: Int で適合する
  • 82. A = Any, B = Int つまり A <: B のとき(Any <:< Int) なimplicitな値が必要
  • 83. (Any <:< Any) <: (Any <: Int) かつ (Int <:< Int) <: (Any <: Int) (<:< の左辺はcontravariant) →コンパイルエラー
  • 84. implicit parameterを使ったライブラリ/フレームワーク
  • 85. Scala標準ライブラリ Scalaz sjson ScalaCheck spray Akka Squeryl ...
  • 86. たくさんある
  • 87. implicit parameterを活用してみてください
  • 88. 通称コップ本 第二版 好評発売中Scala 2.8対応+付録Scala 2.9記事(by @kmizu)
  • 89. 宣伝(2)
  • 90. こんなキーワードにピンと来たら(ry Cakeパターン, CONCEPTパターン, 限定継続 現場でのScala, Javaとの連携

×