SlideShare a Scribd company logo
Scalaで型クラス入門
AMoAd 福原真
2015-11-06 Adtech Scala Meetup
(2015-12-20 外部公開用に改定)
株式会社サイバーエージェント
アドテクスタジオ
AMoAd所属
福原 真
@fukuo33
-2011/08 (主にJava)
SIer として 金融、物流、外食、通信 etc様々なプロジェクトに参加
2011/09- (C言語 + Scala)
某アドネットワークシステム サーバサイドエンジニア
2013/04- (Scala + Java)
株式会社AMoAd サーバサイドエンジニア
自己紹介
このスライドについて
CyberAgent Adtech Studio内で定期的に開催して
いる「Adtech Scala Meetup」向けのスライドで
す。
* 対象
ScalaでHello worldが書ける人
型クラスについて全く知らない人
関数型とか分かんないけど、手っ取り早く型クラスを何か理解し
たい人
このスライドについて
* 概要
まずHaskellベースで型クラスとは何かを説明します。
次にScalaでその型クラスをどう実現するのか説明し
ます。
なるべく初心者向けに簡単に説明する所存です!
このスライドについて
* 話すこと
型
型クラス
アドホック多相
* 話さないこと
型引数
型コンストラクタ
Kind
Monoid
Functor
Applicative
Monad
前置き
型とは?
一旦、オブジェクト指向のクラスを忘れて、型について思い出しましょう。
※ 用語: 型 と データ型 は同意
int i = 123;
char c = 'a';
C言語
Java
int i = 123;
boolean b = true;
// String s = "abc" // String is Class, not data type.
Haskell
Prelude> :t True
True :: Bool
赤枠が"型"です。※クラスではありません。
型における値の範囲
型には取りうる値の範囲が決まっています。
Java
int: -2147483648 .. 2147483647
boolean: true | false
Haskell
Prelude> :i Int
data Int = GHC.Types.I# GHC.Prim.Int#
Prelude> :i Bool
data Bool = False | True
型における値の範囲
Haskellではデータ型を自分で定義できます
(JavaのEnumっぽい?)
Haskell
Prelude> data TrafficLight = Red | Yellow | Green
Prelude> :t Red
Red :: TrafficLight
※ RedはTrafficLight型の "値" です。
型クラスとは?
型クラスとは?
型クラスは、何らかの振る舞いを定義するインターフェースです。
ある型クラスのインスタンスである型は、その型クラスが記述する振
る舞いを実装します。
by 「すごいHaskellたのしく学ぼう!」
* 「型クラスはインターフェースを定義してる」とは?
* 「型クラスのインスタンスである型」とは?
「型クラスのインスタンスである型」とは?
Prelude> 123 == 123
True
Prelude> 'a' == 'b'
False
Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Eq は型クラスです。
a は型です。
Eq a => はa型はEq型クラスのインスタンスである必要がある制約です。
(==)関数は、引数にEq型クラスのインスタンスa型を2つとり、Bool型を返し
ます。
Javaのinterfaceに似てるかも?
Haskell
「型クラスのインスタンスである型」とは?
Prelude> :i Int
data Int = GHC.Types.I# GHC.Prim.Int# -- Defined in ‘GHC.Types’
..
instance Eq Int -- Defined in ‘GHC.Classes’
..
Prelude> :i Char
data Char = GHC.Types.C# GHC.Prim.Char# -- Defined in ‘GHC.Types’
..
instance Eq Char -- Defined in ‘GHC.Classes’
..
Int型も、Char型も、Eq型クラスのインスタンスで
す。
「型クラスはインターフェースを定義してる」とは?
Prelude> :i Eq
class Eq a where
(==) :: a -> a -> Bool
(/=) :: a -> a -> Bool
x == y = not(x/=y)
x /= y = not(x==y)
== 関数 と /= 関数が実装すべき関数(インターフェース)です。
※ Eq型クラスはデフォルト実装が定義されているので、 (==)
を実装すれば最小完全定義を満たせる
「型クラスはインターフェースを定義してる」とは?
Prelude> :i TrafficLight
data TrafficLight = Red | Yellow | Green
Prelude> Red == Red
No instance for (Eq TrafficLight) arising from a use of ‘==’
Prelude> :set +m
Prelude> instance Eq TrafficLight where
Prelude| Red == Red = True
Prelude| Green == Green = True
Prelude| Yellow == Yellow = True
Prelude| _ == _ = False
Prelude|
Prelude> :i TrafficLight
data TrafficLight = Red | Yellow | Green
instance Eq TrafficLight
Prelude> Red == Red
True
自分で定義した型をEq型クラスのインスタンスにしてみる
↑この時点では (==) は使えない
←Eq型クラスのインスタンスにしたので
(==) が使えるようになった!
オブジェクト志向のクラスと何が違うのか?
オブジェクト指向言語(Java, Python, C++)でクラスといえば、何
らかの動作をするオブジェクトを作るための青写真のことです。
でも、Haskellのクラスは、データを作る道具ではありません。
そうではなく、まずデータ型を作り、それから「このデータには何がで
きるんだろう?」と考えるのです。
by 「すごいHaskellたのしく学ぼう!」
つまりdata型宣言時に"特徴"を与えるのではなく
アドホック(場当たり的)に型クラスのインスタンスであることを宣言する。
型クラスはアドホック多相(adhoc polymorphism)を実現していると言えます。
型クラスとは?
型クラスについて聞かれたら「あーアドホック多相
のことねー」と言っとけばなんとかなります!(多
分)
ここからはアドホック多相をScalaでどう実現する
のかを説明します!
多相
(Polymorphis
m)とは?
多相(Polymorphism)とは?
ポリモーフィズムあるいはポリモルフィズム(Polymorphism)と
は、プログラミング言語の型システムの性質を表すもので、プログ
ラミング言語の各要素(定数、変数、式、オブジェクト、関数、メ
ソッドなど)についてそれらが複数の型に属することを許すという
性質を指す。
by Wikipedia
アドホック多相にいく前に、多相覚えてますか?
多相(Polymorphism)とは?
普段、オブジェクト指向言語で使ってるのは
派生型多相(Subtype Polymorphism)
abstract class Animal {
def bark(): String
}
class Cat extends Animal {
def bark() = "にゃあ"
}
class Dog extends Animal {
def bark() = "わん"
}
val animal1 = new Cat()
val animal2 = new Dog()
animal1.bark // "にゃあ"
animal2.bark // "わん"
Scala
多相(Polymorphism)とは?
型パラメータを使うのは
パラメトリック多相(Parametric Polymorphism)
JavaではGenericsって呼ばれますね。
scala> def concat[A](l1: List[A], l2: List[A]) = l1 ++ l2
concat: [A](l1: List[A], l2: List[A])List[A]
scala> concat(List(1, 2, 3), List(4, 5, 6))
res0: List[Int] = List(1, 2, 3, 4, 5, 6)
scala> concat(List("aa", "bb", "cc"), List("dd", "ee", "ff"))
res1: List[String] = List(aa, bb, cc, dd, ee, ff)
Scala
多相(Polymorphism)とは?
オーバーロードはポリモーフィズムの一種
※自信なしです。各自調べてください
class Clazz {
def foo() = "foo"
def foo(b: Boolean) = s"foo: $b"
def foo(s: String) = s"foo: $s"
}
val c = new Clazz()
c.foo() // "foo"
c.foo(true) // "foo: true"
c.foo("huga") // "foo: huga"
Scala
Scalaで
アドホック多
相を実現する
には?
Implicits
Implicit (暗黙の∼∼)は、Scalaで型クラスを実現する
ために導入されたらしい
Poor Man's Type Classs
Martin Odersky
http://lampwww.epfl.ch/~odersky/talks/wg2.8-
boston06.pdf
implicit conversion
暗黙の型変換を使って、アドホックに多相を実現する
scala> c.foo(123)
<console>:13: error: overloaded method value foo with alternatives:
(s: String)String <and>
(b: Boolean)String
cannot be applied to (Int)
c.foo(123)
^
scala> implicit def intToString(i: Int): String = i.toString
warning: there was one feature warning; re-run with -feature for details
intToString: (i: Int)String
scala> c.foo(123)
res8: String = foo: 123
Scala P22の続き
↑この時点ではClazz#foo(Int)は使えない
←暗黙の型変換を定義することによって、
Clazz#foo(Int)が使えるようになった!
implicit parameter
package sample.typeclass



trait Plus[A] {

def plus(a1: A, a2: A): A

}
暗黙のパラメータを使って、アドホックに多相を実現する
package sample



import sample.typeclass.Plus



package object implicits {

implicit object IntPlus extends Plus[Int] {

def plus(a1: Int, a2: Int) = a1 + a2

}

implicit object StringPlus extends Plus[String] {

def plus(a1: String, a2: String) = a1 + a2

}

}
package sample



import sample.typeclass.Plus



package object implicits2 {

implicit object IntPlus extends Plus[Int] {

def plus(a1: Int, a2: Int) = (a1 + a2) + (a1 + a2)

}

implicit object StringPlus extends Plus[String] {

def plus(a1: String, a2: String) = (a1 + a2) + (a1
+ a2)

}

}
sample/typeclass/Plus.scala
sample/implicits/package.scala sample/implicits2/package.scala
Haskellの例(P12)と比較すると
Plus[A] は型クラス。
IntPlus, StringPlus は型。
implicit object IntPlus extends Plus[Int] は、IntPlusは
Plus[A]型クラスのインスタンス。
implicit parameter
scala> import sample.typeclass.Plus
import sample.typeclass.Plus
scala> def plus[A: Plus](a1: A, a2: A)(implicit a: Plus[A]): A =
a.plus(a1, a2)
plus: [A](a1: A, a2: A)(implicit evidence$1:
sample.typeclass.Plus[A], implicit a: sample.typeclass.Plus[A])A
scala> plus(123, 200)
<console>:10: error: could not find implicit value for evidence
parameter of type sample.typeclass.Plus[Int]
plus(123, 200)
^
scala> import sample.implicits._
import sample.implicits._
scala> plus(123, 200)
res1: Int = 323
↓この時点では plus は使えない
← 型クラスインスタンスが定義されたパッケージを
importすることによって、plus()が使えるようになった!
implicit parameter
scala> import sample.implicits2._
import sample.implicits2._
scala> plus(123, 200)
res2: Int = 646
↑ Scalaではimportを切り替えることに
よって、実装が切り替えられる!
Scalaでアドホック多相を使う嬉しさ
よく言う話としては、ライブラリで定義されたfinal classをアドホック
多相にて拡張することができる。
サブタイプ多相のみでも解決できることは多いと思いますが、継承関係
には手を加えずテスト時のみ動作を変えるとか利点があると思います。
※ あとは各自調べて(汗)
開放/閉鎖原則(かいほうへいさげんそく。open/closed principle、OCP)
とは、オブジェクト指向プログラミングにおいて、クラス(およびその他のプ
ログラム単位)は
拡張に対して開いて (open) いなければならず、
修正に対して閉じて (closed) いなければならない
という設計上の原則である。
by Wikipedia
参考
主要な型クラスの紹介 @gakuzzz
https://gist.github.com/gakuzzzz/8d497609012863b3ea50
怖くない型クラス @kmizu
http://www.slideshare.net/kmizushima/ss-28707326
Scala の implicit parameter は型クラスの一種とはどういうことなのか
@nkgt_chkonk
http://nekogata.hatenablog.com/entry/2014/06/30/062342

More Related Content

PPTX
冬のLock free祭り safe
PDF
Dockerからcontainerdへの移行
PDF
SSE4.2の文字列処理命令の紹介
PPTX
分散システムについて語らせてくれ
PDF
関数型プログラミングのデザインパターンひとめぐり
PDF
ゲーム開発者のための C++11/C++14
PPTX
MongoDBが遅いときの切り分け方法
KEY
やはりお前らのMVCは間違っている
冬のLock free祭り safe
Dockerからcontainerdへの移行
SSE4.2の文字列処理命令の紹介
分散システムについて語らせてくれ
関数型プログラミングのデザインパターンひとめぐり
ゲーム開発者のための C++11/C++14
MongoDBが遅いときの切り分け方法
やはりお前らのMVCは間違っている

What's hot (20)

PPTX
イベント・ソーシングを知る
PDF
日本語テストメソッドについて
PPTX
競技プログラミングのためのC++入門
PPTX
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
PDF
オブジェクト指向できていますか?
PDF
例外設計における大罪
PPT
Glibc malloc internal
PDF
中3女子でもわかる constexpr
PDF
並行処理初心者のためのAkka入門
PPTX
はじめての datadog
PPTX
世界一わかりやすいClean Architecture
PPTX
BuildKitによる高速でセキュアなイメージビルド
PDF
マイクロにしすぎた結果がこれだよ!
PDF
コンテナの作り方「Dockerは裏方で何をしているのか?」
PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
PDF
10GbE時代のネットワークI/O高速化
PDF
中級グラフィックス入門~シャドウマッピング総まとめ~
PDF
MySQLで論理削除と正しく付き合う方法
PDF
【Unite Tokyo 2019】Understanding C# Struct All Things
PDF
イミュータブルデータモデル(入門編)
イベント・ソーシングを知る
日本語テストメソッドについて
競技プログラミングのためのC++入門
モノリスからマイクロサービスへの移行 ~ストラングラーパターンの検証~(Spring Fest 2020講演資料)
オブジェクト指向できていますか?
例外設計における大罪
Glibc malloc internal
中3女子でもわかる constexpr
並行処理初心者のためのAkka入門
はじめての datadog
世界一わかりやすいClean Architecture
BuildKitによる高速でセキュアなイメージビルド
マイクロにしすぎた結果がこれだよ!
コンテナの作り方「Dockerは裏方で何をしているのか?」
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
10GbE時代のネットワークI/O高速化
中級グラフィックス入門~シャドウマッピング総まとめ~
MySQLで論理削除と正しく付き合う方法
【Unite Tokyo 2019】Understanding C# Struct All Things
イミュータブルデータモデル(入門編)
Ad

Viewers also liked (20)

PDF
こわくない型クラス
PDF
Scalaのオブジェクトの話
DOCX
Epps project revised
PPTX
Cooltur bea-e-giulia
PPTX
Animasi pada-presentasi (1) call uhamka
PPTX
Orakom
PPT
Grammar book
DOCX
Epps project revised
PPT
Grammar book
PPT
סולמות
PDF
Pythonのすすめ
PDF
Swiftで、かなり微妙な型クラス
PPTX
Javaから始めるscalaっぽい書き方
KEY
Programming haskell chapter10
PDF
第三回ありえる社内勉強会 「いわががのLombok」
ODP
Scala lens: An introduction
PDF
Scalaで実装するGC
PDF
15分でざっくり分かるScala入門
PDF
Python3でwebアプリ
PDF
Scalaで萌える関数型プログラミング[完全版]
こわくない型クラス
Scalaのオブジェクトの話
Epps project revised
Cooltur bea-e-giulia
Animasi pada-presentasi (1) call uhamka
Orakom
Grammar book
Epps project revised
Grammar book
סולמות
Pythonのすすめ
Swiftで、かなり微妙な型クラス
Javaから始めるscalaっぽい書き方
Programming haskell chapter10
第三回ありえる社内勉強会 「いわががのLombok」
Scala lens: An introduction
Scalaで実装するGC
15分でざっくり分かるScala入門
Python3でwebアプリ
Scalaで萌える関数型プログラミング[完全版]
Ad

Similar to Scalaで型クラス入門 (20)

PDF
Phantom Type in Scala
PDF
Haskell勉強会2 in ie
PDF
型クラス
PDF
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
KEY
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
PDF
すごいHaskell読書会
PDF
Scala の関数型プログラミングを支える技術
PDF
What Dotty fixes @ Scala関西サミット
PDF
すごいHaskell読書会 第7章 (前編)
PDF
プログラミング言語Scala
PDF
Python と型ヒント (Type Hints)
PDF
すごいHaskell読書会 in 大阪 #6
PDF
すごいH 第12章モノイド
PDF
Implicit Explicit Scala
PDF
BOF1-Scala02.pdf
PDF
BOF1-Scala02.pdf
PDF
BOF1-Scala02.pdf
PPTX
OUCC LT会2
ODP
これから Haskell を書くにあたって
PDF
Haskell Lecture 2
Phantom Type in Scala
Haskell勉強会2 in ie
型クラス
すごいHaskell 第7章 型や型クラスを自分で作ろう(前編)
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
すごいHaskell読書会
Scala の関数型プログラミングを支える技術
What Dotty fixes @ Scala関西サミット
すごいHaskell読書会 第7章 (前編)
プログラミング言語Scala
Python と型ヒント (Type Hints)
すごいHaskell読書会 in 大阪 #6
すごいH 第12章モノイド
Implicit Explicit Scala
BOF1-Scala02.pdf
BOF1-Scala02.pdf
BOF1-Scala02.pdf
OUCC LT会2
これから Haskell を書くにあたって
Haskell Lecture 2

Scalaで型クラス入門