More Related Content
PPT
PDF
PDF
Introduction to Scala Functional Programming PDF
ODP
PDF
PDF
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】 PDF
Similar to Introduction to Functional Programming
PDF
PDF
オブジェクト指向開発におけるObject-Functional Programming KEY
Clojure programming-chapter-2 PDF
PDF
PDF
命令プログラミングから関数プログラミングへ PDF
PPTX
PDF
PDF
PDF
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ PPTX
PDF
PDF
PDF
PDF
PDF
PPTX
PDF
PDF
More from PIXELAcorporation
PPTX
Introduction to conccrent_lock PPTX
20190620 aws summit_tokyo_2019 PPTX
Global Azure Boot Camp 2019 PPTX
PPTX
Study ocf over_bluetooth_mesh PPTX
PPTX
PPTX
PPTX
4K SmartTV Works with Alexa PPTX
20181228 ncf to_azure_batch PPTX
PPTX
PPTX
Introduction to Functional Programming
- 1.
- 2.
- 3.
Function
Type A =>Type B へのマッピング
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
3
- 4.
- 5.
List::map
List[1, 2, 3].map(i=> i + 1) => List[2, 3, 4]
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
5
- 6.
- 7.
ダイアグラム
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
7
A B
List[A] List[B]
Normal
Lifted
f
List::map コンテナ層に適用可能にする
- 8.
List
List[A] = Headof List :: Tail of List
Tail of List = (Head of (Tail of List)) :: (Tail of (Tail of List))
Tail of Tail of List = …
Tail of Tail of … = Nil
-> Head::TofHead::TTofHead::…Nil
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
8
- 9.
List (scala的)
sealed traitList[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
9
- 10.
fold[Right|Left]
def foldRight[A, B](as:List[A], z:B)(f: (A, B) => B) : B = as match {
case Nil => z
case Cons(x, xs) => f(x, foldRight(xs, z)(f))
}
@annotation.tailrec
def foldLeft[A, B](as: List[A], z:B)(f: (B, A) => B) : B = as match {
case Nil => z
case Cons(x, xs) => foldLeft(xs, f(z, x))(f)
}
関数fが多数回呼ばれる => fに副作用を入れないことがいかに重要か
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
10
- 11.
Folds are primitivefunctions for List class
def List::map[A, B](la:List[A])(f: A -> B) : List[B]=
foldRight(Nil[List[B]])((h, t) => f(h) :: t))
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
11
- 12.
ダイアグラム
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
12
A B
List[A] List[B]
Normal
Lifted
入力
f
入力がList[A]の場合、
f にある操作をして
出力をList[List[B]]ではなく、
List[B] にするには?
List要素 1つ1つで
List[B]ができるf
- 13.
ダイアグラム
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
13
A B
List[A] List[B]
Normal
Lifted
入力
f
f’
f’ を作るには?
- 14.
List::flatMap (scala)
def append[A](la:List[A], lb: List[A]): List[A] = la match {
case Nil => lb
case Cons(h, t) => Cons(h, append(t, lb))
}
def List::flatMap[A, B] (ls: List[A])(f: A => List[B]): List[B] =
foldRight(ls, Nil:List[B])((h, t) => append(f(h), t))
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
14
- 15.
ダイアグラム
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
15
A B
List[A] List[B]
Normal
Lifted
入力
f
f’
List::flatMap
- 16.
- 17.
Imperative Programming Style
TypeAa = funAFromUnit();
TypeB b = funAToB(a);
TypeC c = …
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
17
- 18.
表現方法の変換
chain(x:input, f: x=> y) = f(input)
chain(funAFromUnit(), a =>
chain(funAToB(a), b =>
chain(fun…)))
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
18
- 19.
Functional Programming Style
chain(funAFromUnit(),a =>
chain(funAToB(a), b =>
chain(fun…)))
funAFromUnit() を入力とし、後続全てを丸ごとFunctionであると
捉えられる。 後続中も同様の構造となる。 == 再帰的
Imperative的表現 を Functional 的表現で再現した。
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
19
- 20.
- 21.
- 22.
例 日常のコード
def proc_nest(a:A):C = {
val b = funAtoB(a)
if (isValid(b) == true) {
val c = funBtoC(b)
if (isValid(c) == true) c else Nothing
}
Nothing
}
- 23.
例 日常のコード
Copyright ©PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
23
def proc_flat(a: A) : C = {
val b = funAtoB(a)
if (isValid(b) != true) {
Nothing
}
val c = funBtoC(b)
if (isValid(c) != true) {
Nothing
}
c
}
- 24.
- 25.
別の大問題 => Exceptionの存在
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
25
- 26.
- 27.
- 28.
Railway Programming
Copyright ©PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
28
元ネタ https://fsharpforfunandprofit.com/posts/recipe-part2/
Left(e)
Right(b;B)a:A
f
sealed trait Either[+E, +A]{
…
}
case class Left[+E](value: E) extends Either[E, Nothing]
case class Right[+A](value:A) extends Either[Nothing, A]
Optionalの親戚的
- 29.
Railway function
Copyright ©PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
29
def railway[A, B, E](f: A => B): A => Either[E, B] = a => {
try {
if (a == Nothing) {
Right(Nothing)
}
val result = f(a)
if (isValid(result) == true) Right(result)
else Right(Nothing)
} catch(exception e) {
Left(e)
}
}
- 30.
それぞれを
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
30
Left(e)
Right(c)b
railway(funBtoC)
Left(e)
Right(b)a
railway(funAtoB)
- 31.
連結できたら良くない?
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
31
Left(e)
Right(c)b
Left(e)
Right(b)a
しかし
railway(funAtoB) と railway(funBtoC)の入出力の型式が違う
railway(funAtoB) railway(funBtoC)
- 32.
ダイアグラム
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
32
A B
Either[E, B]
Normal
Lifted
funAtoB
railway(funAtoB)
C
Either[E, C]
railway(funBtoC)
funBtoC
- 33.
ダイアグラム
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
33
A B
Either[E, B]
Normal
Lifted
funAtoB
railway(funAtoB)
C
Either[E, C]
railway(funBtoC)
funBtoC
Either::flatMap
- 34.
flatMap 実装
sealed traitEither[+E, +A]{
def flatMap[EE >: E, B](f : A => Either[EE, B]):
Either[EE, B] = this match {
case Left(e) => Left(e) // * point
case Right(a) => f(a)
}
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
34
- 35.
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
35
Left(e)
Right(c)Right(b)
Left(e)
Right(b)a
railway(funAtoB) Either::flatMap(railway(funBtoC))
Left(e)
- 36.
- 37.
- 38.
例 日常のコード 改
Copyright© PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
38
def proc_rail[A, C, E](a: A) : Either[E, C] = {
Right(a).flatMap(a =>
railway(funAtoB)(a).flatMap(b =>
railway(funBtoC)(b)))
}
- 39.
演算子擬似コード
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
39
def (>>=)[A,B,E](eith:Either[E, A])(f:A => Either[E,
B]):Either[E, B] = {
eith.flatMap(a => f(a))
}
- 40.
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
40
def proc_rail[A, C, E](a: A) : Either[E, C] = {
Right(a)
>>= railway(funAtoB)
>>= railway(funBtoC)
}
演算子>>= を使った擬似コード
- 41.
ダイアグラム
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
41
A B
Either[E, B]
Normal
Lifted
railway(funAtoB)
C
Either[E, C]
railway(funBtoC)
Either[A, E]
- 42.
結合則条件
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
42
Right(a).flatMap(f).flatMap(g) ==
Right(a).flatMap(aa => f(aa).flatMap(g))
→ flatMapの並列結合したものと、 ネストしたflatMapが同値
これと、単位元の存在条件を満たすコンテナクラスの持つ特徴
- 43.
- 44.
- 45.
さらなる応用
List::map(la:List[A], f:A =>Either[E, A]): List[Either[E, A]]
List[Right[A], Left[E], Right[A], …] となる場合を考える。
この時、 Listの中にLeftが出てくることを許容できないケースがある
とする。
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
45
- 46.
List[Either[E, A]] が、Either[E, List[A]] となるようにしたい。
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
46
- 47.
map2
def Either::map2[E, A,B, C](ea: Either[E, A], eb: Either[E, B],
f: (A, B) =>C) : Either[E, C] =
ea.flatMap(a =>
eb.map(b =>
f(a, b)
))
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
47
- 48.
ちょっと脱線 zip
Either::zip[E, A,B](ea: Either[A], eb: Either[E, B]) : Either[E,
(A, B)] =
Either::map2(ea, eb) ((a, b) => (a, b))
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
48
- 49.
sequence
Copyright © PIXELACORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
49
def sequence[E, A](es: List[Either[E, A]]): Either[E, List[A]] =
es.foldRight[Either[E,List[A]]](Right(Nil))((head_e, tail_e) =>
Either::map2(head_e)(tail_e)((head, tail) => head::tail))
- 50.
ダイアグラム sequence
Copyright ©PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
50
A ANormal
Either[A, E]
List[Either[A, E]] Either[List[A], E]
List[A, E]
- 51.
- 52.
追加情報
○ 普段使うコンテナ型クラスはmonad性質がある。
→ 普段のプログラムは、全てmonad性質を持つコンテナ型クラスで構成できる。
○List, Stream (遅延評価)
○ Optional(==Nullable), Either
○ State
○ Async, Parallel
(︎↑を基本とし、さらに上位のライブラリを作れる。
例. テストライブラリ(テストデータ自動生成 & データに対する性質テスト)
パーサーライブラリ(500行程度でパーサーライブラリ&Jsonパーサ合わせたものがかけます)
○ Reader-monad, Writer-Monad, IO-Monad 等もある
○ Monad(継続 == 命令型的記述)に関連して、関数型言語では、特別な記述様式が用意されている
Haskell : do記法, Scala: for記法, F#: computation記法
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
52
- 53.
追加情報
○ unit, flatMapをprimitiveとして、上位Combinatorを実装可能なものが多い。
○ map, mapN, zip, sequnence, transverse…
○ unit, map2 をprimitiveにすることも可能 primitiveの選択性)
○ コンテナ型クラスのメソッドがある規則を満たせば、それらクラスがさらに抽象的なグループに分別できる
例 Functor 属性
map に対する規則 containr::map[A](c:container, f: A => A) について、
container::map(c, (a => a)) == a
が成立するもの
○ 演算に対しても同様にグループ分けもできる。
例 Monoid 属性
結合則 op(op(x, y), z) == op(x, op(y, z)) と単位元 の存在
実例 String , List の加算
=> foldable との関係性につながる
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
53
- 54.
所感
メリット:
○ FPはプログラムを統一型式で表現可能な手段を与えてくれる。
→ “統一“というプログラマがコーディング重要指標にあげる点を、徹底的に実現可能。
→言語を超えた統一表現
○ FPがもつ真のmodular性
デメリット:
学習コストの高さ
FP以外にも、FPと同様の統一型式表現手段があればそれを選択すれば良いですが、恐らくそれも学習コストの高さがあると思います。
結局 2択
皆さんが普段戦っている、プログラムを組む時の大問題”複雑性”に対して
* いわゆる普通の命令型の表現を選択して、一つ一つの処理は簡単だが、結果複雑で大きくなり易いコードを書いていく
or
* 高い学習コストを払ってでも新しい表現を選択し、複雑性を隠蔽できるコードを書いていくか
Copyright © PIXELA CORPORATION. All Rights Reserved.|PIXELA CORPORATION PROPRIETARY AND CONFIDENTIAL.
54
- 55.