More Related Content
PDF
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】 PDF
PDF
ODP
PDF
PPT
PDF
Introduction to Scala Functional Programming PDF
Similar to Introduction to Functional Programming
PDF
PDF
PDF
PDF
PDF
PDF
オブジェクト指向開発におけるObject-Functional Programming PDF
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ PDF
PPTX
PDF
PPTX
KEY
Clojure programming-chapter-2 PDF
命令プログラミングから関数プログラミングへ PDF
PDF
PDF
PDF
PDF
PDF
PPTX
More from PIXELAcorporation
PPTX
PPTX
Introduction to conccrent_lock PPTX
PPTX
PPTX
PPTX
20181228 ncf to_azure_batch PPTX
20190620 aws summit_tokyo_2019 PPTX
Global Azure Boot Camp 2019 PPTX
Study ocf over_bluetooth_mesh PPTX
4K SmartTV Works with Alexa 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.