狠狠撸

狠狠撸Share a Scribd company logo
関数型プログラミング
2014-05-11 at ゆかむ勉強会
Suguru Hamazaki
Introduction to Scala Functional Programming
入?門
ご説明内容
Agenda
Scalaって?
関数型プログラミ
ングって?
ステートマシンをどう
やって実装するの?
もっと抽象化
できるよ!
便利な
ライブラリーがあるよ!
プログラミング言語
Scala Programming Language
オブジェクト指向と
関数型の融合
Have the best of both worlds.
Construct elegant class hierarchies
for maximum code reuse and
extensibility, implement their behavior
using higher-order functions. Or
anything in-between.
— from http://www.scala-lang.org/
Object-Oriented Meets Functional
But …
パラダイムシフトは難しい
A paradigm shift is dif?cult
Introduction to Scala Functional Programming
関数型プログラミング
Functional Programming
純粋関数
Pure Function
純粋関数
Pure Function
? 関数の評価結果が引数の値のみに
よって決まり、同じ値を与えると
常に同じ値の結果を返す
? 関数の評価によって、観測可能な
副作用が発生しない
f
x y
副作用の例Side effects examples
? 変数に再代入する
? データの構造を破壊的に変更する
? オブジェクトのフィールドに値をセットする
? 例外を投げる、エラー時に終了する
? コンソールに出力する、ユーザー入力を読む
? ファイルを読み書きする
? スクリーンに描画する
Variable reassigning
Destructive mutation
Setting ?eld values
Throwing exceptions or stopping at failure
Console output or reading user input
File I/O
Displaying to screen
純粋関数プログラムを書く
Write programs using only
pure functions
のみで
えっ?
コインのモデル
A coin model
head tail
?ip
?ip
stay stay
オブジェクト指向的コイン
case class OoCoin(private var head: Boolean) {	
def flip() = { head = !head }	
def stay() = {} // do nothing	
def get = head	
}
Object-Oriented Coin
オブジェクト指向的コイン
case class OoCoin(private var head: Boolean) {	
def flip() = { head = !head }	
def stay() = {} // do nothing	
def get = head	
}
var (variable) で宣言し
たフィールドに再代入
Object-Oriented Coin
val c = OoCoin(true)	
c.flip()	
c.stay()	
c.flip()	
println("Showing a head? " + c.get)
参照透過性
Referential Transparency
ある式の中で、その式の
値を変えることなく、
等しいもの同士を 置換できること
val a = 5	
sumOfSquares(a + 1, a * 2)
def square(i: Int) = i * i 	
def sumOfSquares(i1: Int, i2: Int) =	
square(i1) + square(i2)
val a = 5	
sumOfSquares(a + 1, a * 2)
def square(i: Int) = i * i 	
def sumOfSquares(i1: Int, i2: Int) =	
square(i1) + square(i2)	
純粋な関数
val a = 5	
sumOfSquares(a + 1, a * 2)
def square(i: Int) = i * i 	
def sumOfSquares(i1: Int, i2: Int) =	
square(i1) + square(i2)	
純粋な関数
再代入できない val
置換モデル
sumOfSquares(a + 1, a * 2)	
sumOfSquares(5 + 1, 5 * 2)	
sumOfSquares(6, 10)	
square(6) + square(10)	
(6 * 6) + (10 * 10)	
36 + 100	
136
Substitution Model
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html
再び、コインの例を見てみる
OK, let’s go back to the coin model
val c = OoCoin(true)	
c.flip()	
c.stay()	
c.flip()	
println("Showing a head? " + c.get)
val c = OoCoin(true)	
c.flip()	
c.stay()	
c.flip()	
println("Showing a head? " + c.get)
mutable なデータ構造と
非純粋関数
val c = OoCoin(true)	
c.flip()	
c.stay()	
c.flip()	
println("Showing a head? " + c.get)
mutable なデータ構造と
非純粋関数
参照透過性は?
不変なコインと
純粋関数を使う
Use immutable coins
and pure functions
case class Coin(head: Boolean)	
!
object Coin1 {	
def flip(c: Coin) = Coin(!c.head)	
def stay(c: Coin) = c	
}
case class Coin(head: Boolean)	
!
object Coin1 {	
def flip(c: Coin) = Coin(!c.head)	
def stay(c: Coin) = c	
}	
case class のフィー
ルドはデフォルトで
immutable
case class Coin(head: Boolean)	
!
object Coin1 {	
def flip(c: Coin) = Coin(!c.head)	
def stay(c: Coin) = c	
}	
case class のフィー
ルドはデフォルトで
immutable
受け取ったCoinは変更せず、新しいCoinを生成
val c0 = Coin(true)	
val c1 = flip(c0)	
val c2 = stay(c1)	
val c3 = flip(c2)	
println("Showing a head? " + c3.head)
val c0 = Coin(true)	
val c1 = flip(c0)	
val c2 = stay(c1)	
val c3 = flip(c2)	
println("Showing a head? " + c3.head)
コインの 操作
クラスで表現してみる
を
Express an ‘Action’ of a coin with a class
case class CoinAction(action: Coin => Coin) extends (Coin => Coin) {	
def apply(c: Coin) = action(c)	
def +(next: CoinAction): CoinAction = CoinAction { c0 =>	
val c1 = action(c0)	
next(c1)	
}	
}
case class CoinAction(action: Coin => Coin) extends (Coin => Coin) {	
def apply(c: Coin) = action(c)	
def +(next: CoinAction): CoinAction = CoinAction { c0 =>	
val c1 = action(c0)	
next(c1)	
}	
}
Coinの状態を遷移さ
せる関数をラップ
case class CoinAction(action: Coin => Coin) extends (Coin => Coin) {	
def apply(c: Coin) = action(c)	
def +(next: CoinAction): CoinAction = CoinAction { c0 =>	
val c1 = action(c0)	
next(c1)	
}	
}
Coinの状態を遷移さ
せる関数をラップ 自身も関数として扱える
case class CoinAction(action: Coin => Coin) extends (Coin => Coin) {	
def apply(c: Coin) = action(c)	
def +(next: CoinAction): CoinAction = CoinAction { c0 =>	
val c1 = action(c0)	
next(c1)	
}	
}
Coinの状態を遷移さ
せる関数をラップ 自身も関数として扱える
「コインを受け取った時に、自
身の action を実行してから、次
の操作を実行する」という関数
case class CoinAction(action: Coin => Coin) extends (Coin => Coin) {	
def apply(c: Coin) = action(c)	
def +(next: CoinAction): CoinAction = CoinAction { c0 =>	
val c1 = action(c0)	
next(c1)	
}	
}
Coinの状態を遷移さ
せる関数をラップ 自身も関数として扱える
関数として呼び出された際に、
ラップした関数を実行
「コインを受け取った時に、自
身の action を実行してから、次
の操作を実行する」という関数
First class Functions
? 引数として渡せる
? 戻り値として返せる
? 変数に代入できる
val flip = CoinAction(c => Coin(!c.head))	
val stay = CoinAction(c => c)
?ip, stay を CoinAction の
インスタンスとして定義
val action = flip + stay + flip	
val c = action(Coin(true))	
println("Showing a head? " + c.head)
+() メソッドで操作を
1つにまとめる
val action = flip + stay + flip	
val c = action(Coin(true))	
println("Showing a head? " + c.head)
+() メソッドで操作を
1つにまとめる
でも、途中の結果も
欲しい時は?
case class CoinAction[A](action: Coin => (Coin, A))	
extends (Coin => (Coin, A)) {	
def apply(c: Coin) = action(c)	
def +[B](next: CoinAction[B]): CoinAction[B] =	
flatMap(_ => next)	
def map[B](f: A => B): CoinAction[B] = CoinAction { c0 =>	
val (c1, a) = apply(c0)	
(c1, f(a))	
}	
def flatMap[B](f: A => CoinAction[B]): CoinAction[B] =	
CoinAction { c0 =>	
val (c1, a) = apply(c0)	
f(a)(c1)	
}	
}
case class CoinAction[A](action: Coin => (Coin, A))	
extends (Coin => (Coin, A)) {	
def apply(c: Coin) = action(c)	
def +[B](next: CoinAction[B]): CoinAction[B] =	
flatMap(_ => next)	
def map[B](f: A => B): CoinAction[B] = CoinAction { c0 =>	
val (c1, a) = apply(c0)	
(c1, f(a))	
}	
def flatMap[B](f: A => CoinAction[B]): CoinAction[B] =	
CoinAction { c0 =>	
val (c1, a) = apply(c0)	
f(a)(c1)	
}	
}
Coinと一緒に任意の型の結果を返す
case class CoinAction[A](action: Coin => (Coin, A))	
extends (Coin => (Coin, A)) {	
def apply(c: Coin) = action(c)	
def +[B](next: CoinAction[B]): CoinAction[B] =	
flatMap(_ => next)	
def map[B](f: A => B): CoinAction[B] = CoinAction { c0 =>	
val (c1, a) = apply(c0)	
(c1, f(a))	
}	
def flatMap[B](f: A => CoinAction[B]): CoinAction[B] =	
CoinAction { c0 =>	
val (c1, a) = apply(c0)	
f(a)(c1)	
}	
}
Coinと一緒に任意の型の結果を返す
遷移した結果を
任意の型に変換する
case class CoinAction[A](action: Coin => (Coin, A))	
extends (Coin => (Coin, A)) {	
def apply(c: Coin) = action(c)	
def +[B](next: CoinAction[B]): CoinAction[B] =	
flatMap(_ => next)	
def map[B](f: A => B): CoinAction[B] = CoinAction { c0 =>	
val (c1, a) = apply(c0)	
(c1, f(a))	
}	
def flatMap[B](f: A => CoinAction[B]): CoinAction[B] =	
CoinAction { c0 =>	
val (c1, a) = apply(c0)	
f(a)(c1)	
}	
}
Coinと一緒に任意の型の結果を返す
遷移した結果を
任意の型に変換する
次の操作と組み合わせる。ただし、
前の結果を元に次の操作を生成する
関数として受け取る
val flip = CoinAction { c =>	
val head = !c.head	
(Coin(head), head)	
}	
val stay = CoinAction(c => (c, c.head))
val flip = CoinAction { c =>	
val head = !c.head	
(Coin(head), head)	
}	
val stay = CoinAction(c => (c, c.head))
Coinと一緒に
Boolean 型の結果を
返す
val action =	
flip.flatMap { _ =>	
stay.flatMap { _ =>	
flip	
}	
}	
val (c, _) = action(Coin(true))	
println("Showing a head? " + c.head)
val action =	
flip.flatMap { _ =>	
stay.flatMap { _ =>	
flip	
}	
}	
val (c, _) = action(Coin(true))	
println("Showing a head? " + c.head)
?ip + stay + ?ip と
同様のコード
val action =	
flip.flatMap { _ =>	
stay.flatMap { _ =>	
flip	
}	
}	
val (c, _) = action(Coin(true))	
println("Showing a head? " + c.head)
?ip + stay + ?ip と
同様のコード
ただし、単なる CoinActionではなく、CoinAction を返
す関数を渡している
val action =	
flip.flatMap { b1 =>	
stay.flatMap { _ =>	
flip.map { b3 =>	
(b1, b3)	
}	
}	
}	
val (_, (b1, b3)) = action(Coin(true))	
println("1st occurrence is a head? " + b1)	
println("3rd occurrence is a head? " + b3)
val action =	
flip.flatMap { b1 =>	
stay.flatMap { _ =>	
flip.map { b3 =>	
(b1, b3)	
}	
}	
}	
val (_, (b1, b3)) = action(Coin(true))	
println("1st occurrence is a head? " + b1)	
println("3rd occurrence is a head? " + b3)
結果が Tuple になるよう
map() で変換
val action =	
flip.flatMap { b1 =>	
stay.flatMap { _ =>	
flip.map { b3 =>	
(b1, b3)	
}	
}	
}	
val (_, (b1, b3)) = action(Coin(true))	
println("1st occurrence is a head? " + b1)	
println("3rd occurrence is a head? " + b3)
結果が Tuple になるよう
map() で変換
?atMap() が受けるのは、今の操作の結果から、次回以降の操作を作る関数。
val action =	
flip.flatMap { b1 =>	
stay.flatMap { _ =>	
flip.map { b3 =>	
(b1, b3)	
}	
}	
}	
val (_, (b1, b3)) = action(Coin(true))	
println("1st occurrence is a head? " + b1)	
println("3rd occurrence is a head? " + b3)
結果が Tuple になるよう
map() で変換
?atMap() が受けるのは、今の操作の結果から、次回以降の操作を作る関数。
なので、b1, b3 がネスト
した内部ブロックで利用
できる
val action = for {	
b1 <- flip	
_ <- stay	
b3 <- flip	
} yield (b1, b3)	
val (_, (b1, b3)) = action(Coin(true))	
println("1st occurrence is a head? " + b1)	
println("3rd occurrence is a head? " + b3)
map(), ?atMap() があれば、for-comprehension が使える
val action = for {	
s1 <- flip.map(b1 => "1st occurrence is a head? " + b1)	
_ <- stay	
s3 <- flip.map(b3 => "3rd occurrence is a head? " + b3)	
} yield (s1 + "n" + s3)	
val (_, s) = action(Coin(true))	
println(s)
val action = for {	
s1 <- flip.map(b1 => "1st occurrence is a head? " + b1)	
_ <- stay	
s3 <- flip.map(b3 => "3rd occurrence is a head? " + b3)	
} yield (s1 + "n" + s3)	
val (_, s) = action(Coin(true))	
println(s)
この時点で、
CoinAction[Boolean] を
CoinAction[String] に変換して
しまう
颁辞颈苍础肠迟颈辞苍を抽象化
case class CoinAction[A](action: Coin => (Coin, A))	
extends (Coin => (Coin, A)) {	
def apply(c: Coin) = action(c)	
def +[B](next: CoinAction[B]): CoinAction[B] =	
flatMap(_ => next)	
def map[B](f: A => B): CoinAction[B] = CoinAction { c0 =>	
val (c1, a) = apply(c0)	
(c1, f(a))	
}	
def flatMap[B](f: A => CoinAction[B]): CoinAction[B] =	
CoinAction { c0 =>	
val (c1, a) = apply(c0)	
f(a)(c1)	
}	
}
case class CoinAction[A](action: Coin => (Coin, A))	
extends (Coin => (Coin, A)) {	
def apply(c: Coin) = action(c)	
def +[B](next: CoinAction[B]): CoinAction[B] =	
flatMap(_ => next)	
def map[B](f: A => B): CoinAction[B] = CoinAction { c0 =>	
val (c1, a) = apply(c0)	
(c1, f(a))	
}	
def flatMap[B](f: A => CoinAction[B]): CoinAction[B] =	
CoinAction { c0 =>	
val (c1, a) = apply(c0)	
f(a)(c1)	
}	
}
Coin のメソッドをどこ
からも呼び出してない
case class State[S, +A](run: S => (S, A)) {	
def map[B](f: A => B): State[S, B] =	
State { s =>	
val (s2, a) = run(s)	
(s2, f(a))	
}	
def flatMap[B](f: A => State[S, B]): State[S, B] =	
State { s =>	
val (s2, a) = run(s)	
f(a).run(s2)	
}	
}
Coin を型パラメーター
S として抽象化
Functional Programming in Scala
http://www.manning.com/bjarnason/ より抜粋、一部改変
type CoinAction[A] = State[Coin, A]	
val flip: CoinAction[Boolean] = State { c =>	
val head = !c.head	
(Coin(head), head)	
}	
val stay: CoinAction[Boolean] = State(c => (c, c.head))
CoinAction を type alias
として定義
先ほどと同じように
使えます
Wait …
それ
でできるよ
Scalaz
Scalaz
Scalaz provides purely functional
data structures to complement those
from the Scala standard library.
— from http://typelevel.org/projects/scalaz/
import scalaz.State	
type CoinAction[A] = State[Coin, A]
scalaz の State を使う
先ほどと同じように
使えます
まとめ
Summary
ScalaはOOとFPがミックスした
マルチパラダイム言語
関数型プログラミングでは
純粋関数を使う
状態遷移を表わす
CoinAction を作り、ステート
マシンを実装した
CoinAction を
State として抽象化
Scalaz の State
を紹介
詳しい解説ドキュメント&
完全なソースコードはこちら
https://github.com/hamazy/scala-fp-calisthenics
Q&A
Image Credits
Ad

Recommended

Start FRP
Start FRP
rf0444
?
Processingによるプログラミング入門 第6回
Processingによるプログラミング入門 第6回
Ryo Suzuki
?
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
Kazunari Hara
?
Frege, What a Non-strict Language
Frege, What a Non-strict Language
y_taka_23
?
Move semantics
Move semantics
mitsutaka_takeda
?
Connect S3 with Kafka using Akka Streams
Connect S3 with Kafka using Akka Streams
Seiya Mizuno
?
Design mvc apps with spotify web api object model
Design mvc apps with spotify web api object model
Takao Tetsuro
?
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ?コーディング Session 2: 構造をつくる
デジタルアートセミナー#2 openFrameworksで学ぶ、 クリエイティブ?コーディング Session 2: 構造をつくる
Atsushi Tadokoro
?
Fpga
Fpga
pramode_ce
?
Gradle 3.0: Unleash the Daemon!
Gradle 3.0: Unleash the Daemon!
Eric Wendelin
?
Introduction to functional programming using Ocaml
Introduction to functional programming using Ocaml
pramode_ce
?
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Mike Hugo
?
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mind
Sander Mak (@Sander_Mak)
?
类别的继承
类别的继承
Justin Lin
?
资料结构
资料结构
Justin Lin
?
Java Tutorial:Learn Java in 06:00:00
Java Tutorial:Learn Java in 06:00:00
Justin Lin
?
Advanced Functional Programming in Scala
Advanced Functional Programming in Scala
Patrick Nicolas
?
Gradle a new Generation Build Tool
Gradle a new Generation Build Tool
Shinya Mochida
?
Introduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
pramode_ce
?
Introduction to Functional Programming
Introduction to Functional Programming
PIXELAcorporation
?
実务者のためのかんたん厂肠补濒补锄
実务者のためのかんたん厂肠补濒补锄
Tomoharu ASAMI
?
モナドハンズオン前座
モナドハンズオン前座
bleis tift
?
厂肠补濒补プログラミング?マニアックス
厂肠补濒补プログラミング?マニアックス
Tomoharu ASAMI
?
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
Tomoharu ASAMI
?
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
Tomoharu ASAMI
?
Refactoring point of Kotlin application
Refactoring point of Kotlin application
Recruit Lifestyle Co., Ltd.
?

More Related Content

Viewers also liked (12)

Fpga
Fpga
pramode_ce
?
Gradle 3.0: Unleash the Daemon!
Gradle 3.0: Unleash the Daemon!
Eric Wendelin
?
Introduction to functional programming using Ocaml
Introduction to functional programming using Ocaml
pramode_ce
?
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Mike Hugo
?
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mind
Sander Mak (@Sander_Mak)
?
类别的继承
类别的继承
Justin Lin
?
资料结构
资料结构
Justin Lin
?
Java Tutorial:Learn Java in 06:00:00
Java Tutorial:Learn Java in 06:00:00
Justin Lin
?
Advanced Functional Programming in Scala
Advanced Functional Programming in Scala
Patrick Nicolas
?
Gradle a new Generation Build Tool
Gradle a new Generation Build Tool
Shinya Mochida
?
Introduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
pramode_ce
?
Gradle 3.0: Unleash the Daemon!
Gradle 3.0: Unleash the Daemon!
Eric Wendelin
?
Introduction to functional programming using Ocaml
Introduction to functional programming using Ocaml
pramode_ce
?
Groovy Grails DevJam Jam Session
Groovy Grails DevJam Jam Session
Mike Hugo
?
Scala: functional programming for the imperative mind
Scala: functional programming for the imperative mind
Sander Mak (@Sander_Mak)
?
Java Tutorial:Learn Java in 06:00:00
Java Tutorial:Learn Java in 06:00:00
Justin Lin
?
Advanced Functional Programming in Scala
Advanced Functional Programming in Scala
Patrick Nicolas
?
Gradle a new Generation Build Tool
Gradle a new Generation Build Tool
Shinya Mochida
?
Introduction to Functional Programming with Scala
Introduction to Functional Programming with Scala
pramode_ce
?

Similar to Introduction to Scala Functional Programming (20)

Introduction to Functional Programming
Introduction to Functional Programming
PIXELAcorporation
?
実务者のためのかんたん厂肠补濒补锄
実务者のためのかんたん厂肠补濒补锄
Tomoharu ASAMI
?
モナドハンズオン前座
モナドハンズオン前座
bleis tift
?
厂肠补濒补プログラミング?マニアックス
厂肠补濒补プログラミング?マニアックス
Tomoharu ASAMI
?
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
Tomoharu ASAMI
?
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
Tomoharu ASAMI
?
Refactoring point of Kotlin application
Refactoring point of Kotlin application
Recruit Lifestyle Co., Ltd.
?
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
Ouka Yuka
?
これから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programming
Tomoharu ASAMI
?
15分でざっくり分かる厂肠补濒补入门
15分でざっくり分かる厂肠补濒补入门
SatoYu1ro
?
たのしい関数型
たのしい関数型
Shinichi Kozake
?
Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
?
これから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
磯野ー!関数型言语やろうぜー!
磯野ー!関数型言语やろうぜー!
Ra Zon
?
Haskell Lecture 2
Haskell Lecture 2
Yusuke Matsushita
?
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
?
Introduction to Functional Programming
Introduction to Functional Programming
PIXELAcorporation
?
実务者のためのかんたん厂肠补濒补锄
実务者のためのかんたん厂肠补濒补锄
Tomoharu ASAMI
?
モナドハンズオン前座
モナドハンズオン前座
bleis tift
?
厂肠补濒补プログラミング?マニアックス
厂肠补濒补プログラミング?マニアックス
Tomoharu ASAMI
?
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
関数モデル 【クラウドアプリケーションのためのオブジェクト指向分析設計講座 第8回】
Tomoharu ASAMI
?
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
Tomoharu ASAMI
?
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
(搁耻产测使いのための)厂肠补濒补で学ぶ関数型プログラミング
Ouka Yuka
?
これから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programming
Tomoharu ASAMI
?
15分でざっくり分かる厂肠补濒补入门
15分でざっくり分かる厂肠补濒补入门
SatoYu1ro
?
Clojure programming-chapter-2
Clojure programming-chapter-2
Masao Kato
?
これから Haskell を書くにあたって
これから Haskell を書くにあたって
Tsuyoshi Matsudate
?
磯野ー!関数型言语やろうぜー!
磯野ー!関数型言语やろうぜー!
Ra Zon
?
F#入門 ~関数プログラミングとは何か~
F#入門 ~関数プログラミングとは何か~
Nobuhisa Koizumi
?
Ad

Introduction to Scala Functional Programming