SlideShare a Scribd company logo
1 of 22
Download to read offline
多相な関数の定義から学ぶ、型クラスデザイン
パターン
twitter: github:@OE_uia taisukeoe
多相な関数
複数の異なる型に対して適用可能な関数
どの型に対して定義されているか、静的に決定できる(定義されてない型の値を渡すとコンパイルエラーになる)
 Int => Int 
 String => String 
 Double => String 
 Seq[Int] => Seq[Int] 
多相な関数のメリット
複数の異なる型に対する操作を一般化したまま変換,合成などを行える
DSLの構築
Heterogeneousなコレクションを簡便に操作できる
一番単純な出発点としての、メソッドの引数オー
バーロード
def overlap(i:Int):Int = i*i 
def overlap(s:String):String = s.foldLeft(""){(l,r) => l + r + r} 
overlap(2) 
//4 
overlap("hoge") 
//hhooggee 
引数オーバーロードのデメリット
(多相のままでは)ETA-EXPANSIONできない
これにより関数合成、変換、など様々な操作ができなくなる
scala> overlap _ 
<console>:13: error: ambiguous reference to overloaded definition, 
both method overlap of type (s: String)String 
and  method overlap of type (i: Int)Int 
match expected type ? 
  overlap _ 
  ^ 
(注: さんにご指摘いただき、一部修正しました)@kmizu
多相を諦めればeta expansionできる
scala> overlap _: (String => String) 
res1: String => String = <function1> 
型消去による衝突
def overlap(seq:Seq[Int]):Seq[Int] = ??? 
def overlap(seq:Seq[String]):Seq[String] = ??? 
<console>:20: error: double definition: 
def overlap(seq: Seq[Int]): Seq[Int] at line 18 and 
def overlap(seq: Seq[String]): Seq[String] at line 20 
have same type after erasure: (seq: Seq)Seq 
     def overlap(seq:Seq[String]):Seq[String] = ??? 
           ^ 
単純な型クラス OVERLAPPABLE
型クラスは、共通の振る舞いを複数の既存の型に追加するための手法
共通の振る舞いのインターフェースを表す型を「型クラス」
共通の振る舞いを追加された型が、実際の振る舞いを定義したインスタンスを「型クラスインスタンス」
Scalaの場合、implicit(暗黙)というキーワードにより型クラスインスタンスを参照する
ここでは、overlap可能という共通の振る舞いを示す型クラスOverlappableと、 IntとStringに対しOverlappableの型クラス
インスタンスを定義している。
def overlap[A,B](a:A)(implicit O:Overlappable[A,B]):B = O overlap a 
trait Overlappable[­A,+B]{ 
  def overlap(a:A):B 
} 
//型クラスのコンパニオンオブジェクトに型クラスインスタンスを定義すると、 
//implicitの探索対象に含まれる 
object Overlappable{ 
  implicit lazy val intOverlap:Overlappable[Int,Int] = 
    new Overlappable[Int,Int]{ 
       def overlap(a:Int):Int = a * a 
  } 
    implicit lazy val stringOverlap:Overlappable[String,String] = 
    new Overlappable[String,String]{ 
     def overlap(s:String):String = s.foldLeft(""){(l,r) => l + r + r} 
  } 
} 
overlap(2) 
overlap("hoge") 
型消去による衝突の回避
暗黙の解決は型消去の前のコンパイルフェイズに行われるため、衝突を回避できる。
implicit lazy val seqIntOverlap:Overlappable[Seq[Int],Seq[Int]] = 
       new Overlappable[Seq[Int],Seq[Int]]{ 
           def overlap(a:Seq[Int]):Seq[Int] = 
                a map Overlappable.intOverlap.overlap 
      } 
implicit lazy val seqStringOverlap:Overlappable[Seq[String],Seq[String]] =
        new Overlappable[Seq[String],Seq[String]]{ 
           def overlap(s:Seq[String]):Seq[String] = 
                s map Overlappable.stringOverlap.overlap 
        } 
scala> overlap(Seq(2)) 
res4: Seq[Int] = List(4) 
scala> overlap(Seq("hoge")) 
res5: Seq[String] = List(hhooggee) 
ETA-EXPANSIONは依然できない
型パラメーターがNothing型に推論される
scala> overlap _ 
<console>:13: error: could not find implicit value for 
    parameter O: Overlappable[Nothing,Nothing] 
     overlap _ 
     ^ 
MAGNET PATTERN
sprayチームが名づけたデザインパターン 参考:
基本的な考え方は先のOverlappable型クラスと同じ
ただしMagnet Patternでは、暗黙の型変換を利用して暗黙のパラメータリストを除いている
spray | Blog » The Magnet Pattern
trait OverlapMagnet{ 
  type Result 
  def value:Result 
} 
object OverlapMagnet{ 
     implicit class IntOverlapMagnet(i:Int) extends OverlapMagnet{ 
     type Result = Int 
       def value = i * i 
     } 
     implicit class StringOverlapMagnet(s:String) extends OverlapMagnet{ 
       type Result = String 
       def value = s.foldLeft(""){(l,r) => l + r + r} 
     } 
} 
def overlap(magnet:OverlapMagnet):magnet.Result = magnet.value 
型消去による衝突の回避
暗黙の解決は型消去の前のコンパイルフェイズに行われるため、衝突を回避できる。
(ほぼ例がOverlappableと一緒なので省略)
ETA-EXPANSION
Dependent Method Typeがあるとeta-expansionできない
scala> overlap _ 
<console>:21: error: method with dependent type 
    (magnet: OverlapMagnet)magnet.Result cannot be converted to function value
   overlap _ 
   ^ 
ただし、オーバーロードされているメソッドの戻り値の型が常に同じであれば、eta-expansion可能
scala> def overlapAndToString(magnet:OverlapMagnet):String = magnet.value.toString
overlapAndToString: (magnet: OverlapMagnet)String 
scala> overlapAndToString _ 
res10: OverlapMagnet => String = <function1> 
(余談)暗黙の引数リストを除くと何が嬉しいのか?
Result型がapplyメソッドを持っていると、impicitな引数リストと衝突する。 applyを多用するDSLには不向き。
def overlap[A,B](a:A)(implicit O:Overlappable[A,B]):B = O overlap a 
trait Overlappable[­A,+B]{ 
  def overlap(a:A):B 
} 
class IntResult(i:Int){ 
  def apply():Int = i 
} 
object Overlappable{ 
  implicit lazy val intOverlap:Overlappable[Int,IntResult] = 
     new Overlappable[Int,IntResult]{
     def overlap(a:Int):IntResult = new IntResult(a * a) 
  } 
} 
scala> overlap(2)() 
<console>:13: error: not enough arguments for method 
           overlap: (implicit O: Overlappable[Int,B])B. 
Unspecified value parameter O. 
       overlap(2)() 
                 ^ 
POLY
型でインデックスされた関数のリスト
Poly自身は型クラスではなく、内部クラスであるPoly#Caseが型クラス。多重定義したい個々の関数に相当する.
Poly#applyを通じて関数を適用する
Shapelessで実装されている
trait Poly{ 
  final def at[A] = new { 
     def apply[B](f:A => B):Case[A,B] = new Case[A,B]{ 
      def apply(a:A) = f(a) 
     } 
  } 
  sealed trait Case[A,B]{ def apply(a:A):B } 
  def apply[A,B](a:A)(implicit C:this.Case[A,B]):B = C(a) 
} 
object overlap extends Poly{ 
    implicit val intOv = at[Int]{_ * 2} 
    implicit val stringOv = at[String]{_.foldLeft(""){(l,r) => l + r + r}} 
} 
overlap(2) 
overlap("hoge") 
※ Shapelessの実装ではなく、単純化した @djspiewak さんの の例を引用Roll your own Shapeless
POLY.APPLYにおける暗黙の値の探索HACK
trait Poly{ 
 //... 
 def apply[A,B](a:A)(implicit C:this.Case[A,B]):B = C(a) 
 //... 
} 
クラスのコンパニオンオブジェクトのメンバーに型クラスインスタンスを定義すると、そのクラスにおけるimplicitの探索対
象に含まれる
オブジェクトのクラスの、コンパニオンオブジェクトはそのオブジェクト自身(!)
Polyを継承したオブジェクトを定義すると、そのオブジェクト(overlap)のメンバもimpilicitの探索対象に含まれる
具体的には object overlap がPolyを継承すると this.Case = overlap.type.Case
overlap.type.Case 型の暗黙のパラメーターの探索対象には、 overlap.typeのコンパニオンオブジェクトが含まれる
overlap.type のコンパニオンオブジェクトは、object overlapである
ゆえにobject overlapのメンバーとして定義した暗黙の値Case[A,B]は、Poly#applyの探索対象となる。
ETA EXPANSION
overlapはobjectなので当然eta expansionできない。
overap.applyも型パラメータがNothingに推論されるため、eta expansionできない。
scala> overlap _ 
<console>:14: error: _ must follow method; cannot follow overlap.type 
     overlap _ 
         ^ 
scala> overlap.apply _ 
<console>:14: error: could not find implicit value for 
               parameter C: overlap.Case[Nothing,Nothing] 
     overlap.apply _ 
                 ^ 
ETA EXPANSIONできないけど…?
は合成可能本家ShapelessのPoly
以下抜粋
trait Poly extends PolyApply with Serializable { 
      import poly._ 
    def compose(f: Poly) = new Compose[this.type, f.type](this, f) 
    def andThen(f: Poly) = new Compose[f.type, this.type](f, this) 
        //... 
} 
class Compose[F, G](f : F, g : G) extends Poly 
object Compose { 
  implicit def composeCase[C, F <: Poly, G <: Poly, T, U, V] 
    (implicit unpack: Unpack2[C, Compose, F, G], 
     cG : Case1.Aux[G, T, U], 
     cF : Case1.Aux[F, U, V]) = 
        new Case[C, T :: HNil] { 
             type Result = V 
             val value = (t : T :: HNil) => cF(cG.value(t)) 
        } 
} 
//以下自動生成されたコード 
type Case1[Fn, A] = Case[Fn, A :: HNil] 
object Case1 { 
    type Aux[Fn, A, Result0] = Case[Fn, A :: HNil] { type Result = Result0 }
    def apply[Fn, A, Result0](fn : (A) => Result0): Aux[Fn, A, Result0] = 
        new Case[Fn, A :: HNil] { 
             type Result = Result0 
           val value = (l : A :: HNil) => l match { case a :: HNil => fn(a) }
      } 
} 
trait Unpack2[­P, F[_, _], T, U] 
object Unpack2 { 
      implicit def unpack2[F[_, _], T, U]: Unpack2[F[T, U], F, T, U] = 
           new Unpack2[F[T, U], F, T, U] {} 
} 
AUXパターン
補助、という意味の「Auxiliary」から来ているパターン
型メンバーを型パラメーターにマッピングする
Shapelessで重度に使われている
trait Overlap[A]{ 
     type Result 
     def value(a:A):Result 
} 
object Overlap{ 
     type Aux[A0,B0] = Overlap[A0]{type Result = B0} //型メンバーを型パラメータにマップする
     implicit def intOverlap:Overlap.Aux[Int,Int] = new OverlapMagnet[Int]{ 
       type Result = Int 
       def value(i:Int):Int = i + i 
     } 
} 
trait Semigroup[A]{ 
     def append(a:A,a2:A):A 
} 
object Semigroup{ 
   implicit val int:Semigroup[Int] = new Semigroup[Int]{ 
     def append(a:Int,a2:Int):Int = a + a2 
   } 
} 
SCALAの同一引数リスト内の値について:
他方の型パラメーターには依存可能
他方の型メンバー(Dependent Method Type)には依存不可能(subsequent argument listのみ)
これを活用して、型クラスから他方の型クラスへ依存する(処理を渡す)ことができる。
def overlap[A,B](a:A)(implicit O:Overlap.Aux[A,B], S:Semigroup[B]):B = 
   S.append(O.value(a),O.value(a)) 
まとめ
型クラスを利用して多相な関数を様々な方法で実装できるが、それぞれ一長一短ある
型クラス + 型メンバー + Dependency Method Typeにより色々と面白いことができる
Shapelessは型クラスのテクニックの宝庫なので、ソース読んでみるととても勉強になります。 (ただソースの自動生成やマ
クロなどにもあふれていて、読みやすいわけでは…)。

More Related Content

What's hot

プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードShigenori Sagawa
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターンMoriharu Ohzu
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPAkira Takahashi
 
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らないdigitalghost
 
ジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fallジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fallnagise
 
2010 icse-an analysis of the variability in forty preprocessor-based software...
2010 icse-an analysis of the variability in forty preprocessor-based software...2010 icse-an analysis of the variability in forty preprocessor-based software...
2010 icse-an analysis of the variability in forty preprocessor-based software...n-yuki
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdfHiroshi Ono
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!Akihiro Nishimura
 
C++ Template Metaprogramming
C++ Template MetaprogrammingC++ Template Metaprogramming
C++ Template MetaprogrammingAkira Takahashi
 
JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]Kenji Kazumura
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみたSatoshi Sato
 
Template Meta Programming入門から応用まで
Template Meta Programming入門から応用までTemplate Meta Programming入門から応用まで
Template Meta Programming入門から応用までyoshihikoozaki5
 
とあるFlashの自動生成
とあるFlashの自動生成とあるFlashの自動生成
とあるFlashの自動生成Akineko Shimizu
 

What's hot (20)

プログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコードプログラムの処方箋~健康なコードと病んだコード
プログラムの処方箋~健康なコードと病んだコード
 
Emcpp item31
Emcpp item31Emcpp item31
Emcpp item31
 
クロージャデザインパターン
クロージャデザインパターンクロージャデザインパターン
クロージャデザインパターン
 
What is template
What is templateWhat is template
What is template
 
Sharing Deep Dive
Sharing Deep DiveSharing Deep Dive
Sharing Deep Dive
 
Boost Fusion Library
Boost Fusion LibraryBoost Fusion Library
Boost Fusion Library
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
Replace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JPReplace Output Iterator and Extend Range JP
Replace Output Iterator and Extend Range JP
 
君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない君はまだ,本当のプリプロセスを知らない
君はまだ,本当のプリプロセスを知らない
 
ジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fallジェネリクスの基礎と応用 JJUG CCC 2012 Fall
ジェネリクスの基礎と応用 JJUG CCC 2012 Fall
 
2010 icse-an analysis of the variability in forty preprocessor-based software...
2010 icse-an analysis of the variability in forty preprocessor-based software...2010 icse-an analysis of the variability in forty preprocessor-based software...
2010 icse-an analysis of the variability in forty preprocessor-based software...
 
BOF1-Scala02.pdf
BOF1-Scala02.pdfBOF1-Scala02.pdf
BOF1-Scala02.pdf
 
Purescript with Monad
Purescript with MonadPurescript with Monad
Purescript with Monad
 
Emcpp0506
Emcpp0506Emcpp0506
Emcpp0506
 
すごいConstたのしく使おう!
すごいConstたのしく使おう!すごいConstたのしく使おう!
すごいConstたのしく使おう!
 
C++ Template Metaprogramming
C++ Template MetaprogrammingC++ Template Metaprogramming
C++ Template Metaprogramming
 
JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]JavaDayTokyo2015 [3-1]
JavaDayTokyo2015 [3-1]
 
闇魔術を触ってみた
闇魔術を触ってみた闇魔術を触ってみた
闇魔術を触ってみた
 
Template Meta Programming入門から応用まで
Template Meta Programming入門から応用までTemplate Meta Programming入門から応用まで
Template Meta Programming入門から応用まで
 
とあるFlashの自動生成
とあるFlashの自動生成とあるFlashの自動生成
とあるFlashの自動生成
 

Similar to 多相な関数の定義から学ぶ、型クラスデザインパターン

Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんかcch-robo
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)Hiro H.
 
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesNoritada Shimizu
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介fukuoka.ex
 
Linq To Fun
Linq To FunLinq To Fun
Linq To Fundeflis
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研dmcc2015
 
Mesh tensorflow
Mesh tensorflowMesh tensorflow
Mesh tensorflowkuroko
 
Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)Yuto Takei
 
flow による型のある世界入門
flow による型のある世界入門flow による型のある世界入門
flow による型のある世界入門sairoutine
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Takuya Matsunaga
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門Shohei Arai
 
Androidで動かすはじめてのDeepLearning
Androidで動かすはじめてのDeepLearningAndroidで動かすはじめてのDeepLearning
Androidで動かすはじめてのDeepLearningMiyoshi Kosuke
 
Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait Uehara Junji
 
初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)Masahiro Hayashi
 
JJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/GrailsJJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/GrailsUehara Junji
 

Similar to 多相な関数の定義から学ぶ、型クラスデザインパターン (20)

Flutterを体験してみませんか
Flutterを体験してみませんかFlutterを体験してみませんか
Flutterを体験してみませんか
 
Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7Pfi Seminar 2010 1 7
Pfi Seminar 2010 1 7
 
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
C++のSTLのコンテナ型を概観する @ Ohotech 特盛 #10(2014.8.30)
 
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介
 
Linq To Fun
Linq To FunLinq To Fun
Linq To Fun
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研
 
Mesh tensorflow
Mesh tensorflowMesh tensorflow
Mesh tensorflow
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)Hello Dark-Side C# (Part. 1)
Hello Dark-Side C# (Part. 1)
 
flow による型のある世界入門
flow による型のある世界入門flow による型のある世界入門
flow による型のある世界入門
 
Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版Dalvikバイトコードリファレンスの読み方 改訂版
Dalvikバイトコードリファレンスの読み方 改訂版
 
JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門JavaScript経験者のためのGo言語入門
JavaScript経験者のためのGo言語入門
 
Androidで動かすはじめてのDeepLearning
Androidで動かすはじめてのDeepLearningAndroidで動かすはじめてのDeepLearning
Androidで動かすはじめてのDeepLearning
 
Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait Introduce Groovy 2.3 trait
Introduce Groovy 2.3 trait
 
初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)初心者講習会資料(Osaka.R#7)
初心者講習会資料(Osaka.R#7)
 
Refactoring point of Kotlin application
Refactoring point of Kotlin applicationRefactoring point of Kotlin application
Refactoring point of Kotlin application
 
C#勉強会
C#勉強会C#勉強会
C#勉強会
 
JJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/GrailsJJUG CCC 2012 Real World Groovy/Grails
JJUG CCC 2012 Real World Groovy/Grails
 

More from Taisuke Oe

プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」Taisuke Oe
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1Taisuke Oe
 
Monix Taskが便利だという話
Monix Taskが便利だという話Monix Taskが便利だという話
Monix Taskが便利だという話Taisuke Oe
 
How to get along with implicits
How to get along with implicits How to get along with implicits
How to get along with implicits Taisuke Oe
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットTaisuke Oe
 
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Taisuke Oe
 
AuxパターンをDottyで解決する
AuxパターンをDottyで解決するAuxパターンをDottyで解決する
AuxパターンをDottyで解決するTaisuke Oe
 
Real World Android Akka
Real World Android AkkaReal World Android Akka
Real World Android AkkaTaisuke Oe
 
Real world android akka
Real world android akkaReal world android akka
Real world android akkaTaisuke Oe
 
Android BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsAndroid BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsTaisuke Oe
 
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~Taisuke Oe
 

More from Taisuke Oe (11)

プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」プレScalaMatsuri2019「スピーカー入門」
プレScalaMatsuri2019「スピーカー入門」
 
How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1How to start functional programming (in Scala): Day1
How to start functional programming (in Scala): Day1
 
Monix Taskが便利だという話
Monix Taskが便利だという話Monix Taskが便利だという話
Monix Taskが便利だという話
 
How to get along with implicits
How to get along with implicits How to get along with implicits
How to get along with implicits
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
 
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版Real World Android Akka - 日本語版
Real World Android Akka - 日本語版
 
AuxパターンをDottyで解決する
AuxパターンをDottyで解決するAuxパターンをDottyで解決する
AuxパターンをDottyで解決する
 
Real World Android Akka
Real World Android AkkaReal World Android Akka
Real World Android Akka
 
Real world android akka
Real world android akkaReal world android akka
Real world android akka
 
Android BLEのつらみを予防するTips
Android BLEのつらみを予防するTipsAndroid BLEのつらみを予防するTips
Android BLEのつらみを予防するTips
 
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
 

多相な関数の定義から学ぶ、型クラスデザインパターン