Submit Search
第一回社内 Scala 勉強会(一部抜粋)
•
15 likes
•
1,992 views
L
lyrical_logical
Follow
社内勉強会の資料から一部抜粋 アップロード時点でまだ勉強は実施されていない :-(
Read less
Read more
1 of 32
Download now
Downloaded 13 times
More Related Content
第一回社内 Scala 勉強会(一部抜粋)
1.
Scala の言語機能
ここからが本番です 全ての言語機能について語るのは無理 本が書けるよ(多分上下巻)! Scala で何ができるようになるか、を重点した つもり… https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
2.
Scala の言語機能 –
型に対する制約 Java の場合 Nominal Subtyping あるクラスと派生クラスの関係に基づく制約 public class Duck { … } public class UglyDuck extends Duck { … } public class DuckBreeder<T extends Duck> { … } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
3.
Scala の言語機能 –
型に対する制約 Java の場合 Nominal Subtyping あるクラスと派生クラスの関係に基づく制約 予め継承している必要がある public class Duck { … } public class UglyDuck extends Duck { … } public class DuckBreeder<T extends Duck> { … } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
4.
Scala の言語機能 –
型に対する制約 Scala の場合 Nominal Subtyping 勿論 Scala にもある class Duck { … } class UglyDuck extends Duck { … } class DuckBreeder[T <: Duck] { … } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
5.
Scala の言語機能 –
型に対する制約 Java の場合 Nominal Subtyping あるクラスとその派生型のみを許容 予め継承している必要がある 問題点:機能を備えていても、継承していないとダメ public static boolean genericIsEmpty<T extends ???>(T t) { return t.isEmpty(); } // String も List も isEmpty を持ってはいるが… genericIsEmpty(“”); genericIsEmpty(new ArrayList()); https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
6.
Scala の言語機能 –
型に対する制約 Scala の場合 Structural Subtyping クラスの構造に基づく制約 必要な機能を備えてさえいれば、継承関係は必要ない type HasIsEmpty = { def isEmpty(): Boolean } def genericIsEmpty[T <: HasIsEmpty](t: T) = t.isEmpty() genericIsEmpty(“”) genericIsEmpty(new java.util.ArrayList()) https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
7.
Scala の言語機能 –
型に対する制約 Scala の場合 Structural Subtyping クラスの構造に基づく制約 必要な機能を備えてさえいれば、継承関係は必要ない 実は名前をつける必要も制約にする必要もない def genericIsEmpty(v: { def isEmpty(): Boolean }) = v.isEmpty() genericIsEmpty(“”) genericIsEmpty(new java.util.ArrayList()) https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
8.
Scala の言語機能 –
型に対する制約 Scala の場合 Structural Subtyping クラスの構造に基づく制約 必要な機能を備えてさえいれば、継承関係は必要ない 実装にはリフレクションが使われているので注意 通常のメソッド呼び出しに比べると遙かに遅い メソッドキャッシュもあるし、そこまで気にしなくてもいいけれど… 分割コンパイルの実現のために仕方なくこうなっている https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
9.
Scala の言語機能 –
型に対する制約 Java の場合 機能を備えていないが、定義することができる場合 問題点:制約がどうのこうの以前の問題だ… public static char genericHead<T extends ???>(T t) { return t.head(); } genericHead(“akari”); https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
10.
Scala の言語機能 –
型に対する制約 Java の場合 機能を備えていないが、定義することができる場合 問題点:制約がどうのこうの以前の問題だ… 解決:Adapter pattern(GoF) を利用する public interface Headable { char head(); } public class StringHeadableAdapter implements Headable { private String str; public StringHeadable(String str) { this.str = str; } @Override public char head() { return str.charAt(0); } } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
11.
Scala の言語機能 –
型に対する制約 Java の場合 機能を備えていないが、定義することができる場合 問題点:制約がどうのこうの以前の問題だ… 解決:Adapter pattern(GoF) を利用する 問題点:一々 Adapter 通すのが面倒… public static char genericHead<T extends Headable>(T t) { return t.head(); } genericHead(new StringHeadableAdapter(“akari”)); https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
12.
Scala の言語機能 –
型に対する制約 Scala の場合 機能を備えていないが、定義することができる場合 Implicit Conversions により機能を備えた型に変換 Implicit と修飾された引数を一つ取る関数により定義 trait Headable { def head(): Char } class StringHeadable(str: String) extends Headable { def head() = str.charAt(0) } implicit def stringIsHeadable(str: String) = new StringHeadable(str) https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
13.
Scala の言語機能 –
型に対する制約 Scala の場合 機能を備えていないが、定義することができる場合 Implicit Conversions により機能を備えた型に変換 Implicit と修飾された引数を一つ取る関数により定義 View Bounds と呼ばれる型制約が利用可能 // T から Headable へ暗黙に変換可能なことを要求 def genericHead[T <% Headable](t: T) = t.head() https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
14.
Scala の言語機能 –
型に対する制約 Scala の場合 機能を備えていないが、定義することができる場合 Implicit Conversions により機能を備えた型に変換 Implicit と修飾された引数を一つ取る関数により定義 View Bounds と呼ばれる型制約が利用可能 変換は暗黙に行われる Java の問題点を解決 明示的に変換することもできる genericHead(“akari”) genericHead(stringIsHeadable(“akari”)) genericHead(new StringHeadable(“akari”)) https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
15.
Scala の言語機能 –
型に対する制約 Pimp My Library (pattern) Implicit Conversions による機能追加の名称 Scala 標準ライブラリでも普通に使われている Scala の String は java.lang.String でも何故か何もしなくても head メソッドが呼べてしまう 予めリッチな型への暗黙変換が定義されているため 他にも色々 RichXXX とか WrappedXXX とか XXXOps とか https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
16.
Scala の言語機能 –
型に対する制約 Pimp My Library と他言語の機能の比較 Ruby の Open Classes グローバルに影響してしまう Scala なら import によりコントロール可能 メソッドが「本当に」追加される(善し悪しは兎も角) 動的型付きなので型制約に関しては特になし C# の Exntension Methods 単なる Syntax Sugar に過ぎない よって、拡張したクラスが満たすことのできる制約は増えない https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
17.
Scala の言語機能 –
型に対する制約 Implicit Conversions の弱点 定義が面倒なことがある 2.10 で導入される Implicit Classes である程度解決 変換の度に中間オブジェクトが生成される 2.10 で導入される Value Classes で解決 C# の Extension Methods とほとんど同じ 暗黙に行われるため、コードが追いづらい Eclipse, IntelliJ IDEA なら変換箇所はハイライトされる 頑張れ https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
18.
Scala の言語機能 –
型に対する制約 ちょっと戻る https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
19.
Scala の言語機能 –
型に対する制約 Java の場合 機能を備えていないが、定義することができる場合 問題点:制約がどうのこうの以前の問題だ… 解決:Adapter pattern をちょっと変形して利用 何を扱う Adapter なのかを型パラメタを取ることで分かるように public interface Headable<T> { char head(T t); } public class StringHeadable implements Headable<String> { @Override public char head(String str) { return str.charAt(0); } } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
20.
Scala の言語機能 –
型に対する制約 Java の場合 機能を備えていないが、定義することができる場合 問題点:制約がどうのこうの以前の問題だ… 解決:Adapter pattern をちょっと変形して利用 問題点:やっぱり面倒… 型情報から何とかして適切な Adapter を選択できないか? public static char genericHead<T>(T t, Headable<T> ev) { return ev.head(t); } genericHead(“akari”, new StringHeadable()); https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
21.
Scala の言語機能 –
型に対する制約 Scala の場合 機能を備えていないが、定義することができる場合 Implicit Patameter により機能を備えた値を要求 値は「型に基づいて」自動的に探索される(詳細は後述) Adapter Pattern をちょっと変形したのはこれのため Java の問題点解決! def genericHead[T](T t)(implicit ev: Headable[T]) = { ev.head(t) } genericHead(“akari”) // ev は適切な値が見つかれば自動的に渡される https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
22.
Scala の言語機能 –
型に対する制約 Scala の場合 機能を備えていないが、定義することができる場合 Implicit Patameter により機能を備えた値を要求 Context Bounds と呼ばれる型制約も利用可能 直接は使わないが、必要とするメソッドを呼ぶとき等に // Headable[T] が暗黙に定義されていることを要求 def genericHeadAsString[T : Headable](T t) = { genericHead(t).toString } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
23.
Scala の言語機能 –
型に対する制約 Scala の場合 機能を備えていないが、定義することができる場合 Implicit Patameter により機能を備えた値を要求 implicit と修飾された val, var, def, object が対象 var はやめておきましょうね… trait Headable[T] { def head(t: T): Char } implicit object stringHeadable extends Headable[String] { def head(str: String) = str.charAt(0) } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
24.
Scala の言語機能 –
型に対する制約 Scala の Implicit Parameters 引数の候補はどこから選ばれる? メソッドの利用箇所から見える定義群と(自明) 要求されている型のコンパニオンオブジェクト内から 複数見つかった場合は? 最も定義場所の近い物が優先される 同じ名前空間で複数見つかった場合はエラー https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
25.
Scala の言語機能 –
型に対する制約 コンパニオンオブジェクトとは? クラスと同名のオブジェクト User オブジェクトはコンパニオンオブジェクト ここではこれ以上は触れません class User(name: String, age: Int) object User { … } https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
26.
Scala の言語機能 –
型に対する制約 _人人人人人人人人人人_ > 突然の Type Classes <  ̄Y^Y^Y^Y^Y^Y^Y^Y ̄ https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
27.
Scala の言語機能 –
型に対する制約 Scala の Implicit Parameters 実は Type Classes を実現するための言語機能 これまでのコードは下の Haskell コードと完全に一致 完全に一致、分かりましたですね? class Headable a where head :: a -> Char instance Headable String where head str = str !! 0 headAsString :: Headable a => a -> String headAsString a = show (head a) https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
28.
Scala の言語機能 –
型に対する制約 Type Classes Functor, Applicative, Monad … じゃない!! モナモナするためだけのものではない Type Classes = 型に機能を外から与える仕組み あれ…なんだかデジャブ? Implicit Conversions と Implicit Parameters って似てる? 実は Implicit Conversions も似たような物 手前味噌ですが参考 より詳細な話は今回はしません https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
29.
Scala の言語機能 –
型に対する制約 標準ライブラリにおける Type Classes の実例 scala.reflect.ClassManifest ClassManifest[T] は T の型情報を扱う 配列の生成時によく使われる scala.collection.generic.CanBuildFrom CanBuildFrom[From, Elem, To] 三つも型パラメタが! From というコレクションから Elem を要素とする To というコレクションを生成する ための Builder[Elem, To] を提供する https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
30.
Scala の言語機能 –
型に対する制約 Implicit Parameters のその他の用法 Type Classes と全く関係ない利用法も Fighting type erasure(pdf 注意、スライドです) 何らかのコンテキストを引き回す android.os.Context の引き回し 弊社のアンドロイドアプリのコードでも使われている play.api.Application の引き回し 弊社の API サーバーのコードでも使われている play.api.db.Connection の引き回し 弊社の API サーバーのコードでも使われて…なかった https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
31.
Scala の言語機能 –
型に対する制約 まとめ 1 Structural Subtyping 継承関係ではなく構造に基づいた制約が可能 Implicit Conversions(View Bounds) 暗黙に変換可能かどうかに基づいた制約が可能 実は Implicit Parameters と大差ない Implicit Parameters(Context Bounds) 暗黙に定義されているかどうかに基づいた制約が可能 実は Type Classes が実現可能 https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
32.
Scala の言語機能 –
型に対する制約 まとめ 2 Scala では様々な種類の型に対する制約がある 制約の種類が多い=柔軟に抽象的な設計が可能 アブストラクションヤッター! 触れなかったこと Variance Type constructor parameters Lower bounds これはまあ Java にもあるしね… forSome https://lepidum.co.jp/ Copyright © 2004-2012 Lepidum Co. Ltd. All rights reserved. Confidential
Download