F# による関数プログラミング入門
中山裕貴
Aiming 大阪スタジオ エンジニア勉強会
2013 年 5 月 27 日
Functional Programming?
Functional Programming?
Functional の意味はどれでしょう?
Functional Programming?
Functional の意味はどれでしょう?
• 機能
Functional Programming?
Functional の意味はどれでしょう?
• 機能
• (数学の)関数
Functional Programming?
Functional の意味はどれでしょう?
• 機能
• (数学の)関数
• 実用
Functional Programming?
Functional の意味はどれでしょう?
• 機能
• (数学の)関数
• 実用
関数プログラミングという手法
“関数をデータに適用する” 手法
関数をデータに適用すると…
関数をデータに適用すると…
• 小さな関数を組み合わせることによる抽象度
の向上
関数をデータに適用すると…
• 小さな関数を組み合わせることによる抽象度
の向上
• バグも入り込みにくい小さな関数をつなげて
大きな関数を作る
関数をデータに適用するために必要なもの
関数をデータに適用するために必要なもの
• 小さな関数を組み合わせる
− > 関数が第一級であるほうが便利
関数をデータに適用するために必要なもの
• 小さな関数を組み合わせる
− > 関数が第一級であるほうが便利
• 名前をつけたくない関数の存在
− > ラムダ式
関数をデータに適用するために必要なもの
• 小さな関数を組み合わせる
− > 関数が第一級であるほうが便利
• 名前をつけたくない関数の存在
− > ラムダ式
• 同じデータであれば同じ結果であってほしい
− > 破壊的代入を持たない
− > 関数や型の再帰的定義を利用
言葉に関する注意点
山本和彦さんの “関数プログラミングの道しるべ” より抜粋(資料リ
ンク)
関数型言語とは…
関数プログラミングの手法を提供、推奨している
言語
と考えるのがわかりやすい
F# による関数プログラミング紹介
F#
• Microsoft Research が開発
• FP と OOP によるマルチパラダイム
• 静的型付け、.NET 基盤
• コンパイラのソースコードが公開されている
ん?
ん?
.NET といえば C# . . .
ん?
.NET といえば C# . . .
• C# には LINQ あるよね?
ん?
.NET といえば C# . . .
• C# には LINQ あるよね?
• ラムダ式も導入されているし…
ん?
.NET といえば C# . . .
• C# には LINQ あるよね?
• ラムダ式も導入されているし…
• 別に F# でなくても良くない?
そういうわけでもない
そういうわけでもない
C# では
そういうわけでもない
C# では
• 関数が第一級オブジェクトではない
そういうわけでもない
C# では
• 関数が第一級オブジェクトではない
• ラムダ式を使える範囲も限定的
そういうわけでもない
C# では
• 関数が第一級オブジェクトではない
• ラムダ式を使える範囲も限定的
• 破壊的代入を許可している
そういうわけでもない
C# では
• 関数が第一級オブジェクトではない
• ラムダ式を使える範囲も限定的
• 破壊的代入を許可している
• 型を手軽に定義やすいわけではない、etc
− > 本日のスコープ外
というわけで
というわけで
• メインパラダイムの違いは差が大きい
というわけで
• メインパラダイムの違いは差が大きい
• より良い C# コードを書く勉強の一環として、
少し触ってみましょう
まず型定義 
type EquipmentType =
| Weapon
| Protector
type Rarity =
| Common
| UnCommon
| Rare
| SuperRare
| UltraRare
type Equipment = {
name : string
ability : decimal
rarity : Rarity
equipmentType : EquipmentType }
補正付き合計攻撃力の算出 
(* decimal - Equipment list - decimal *)
let totalCorrectionOffensiveAbility correctionValue equipments =
equipments
| List.filter (fun e - e.equipmentType = Weapon)
| List.fold (fun acc e - acc + e.ability) 0m
| if correctionValue  0m then (*) (1m + correctionValue) else id
(* Equipment list - unit *)
let printCorrectionOffensiveAbility equipments =
equipments
| totalCorrectionOffensiveAbility 0.33m
| printfn 補正付き合計攻撃力:%M
簡易ゲームループ 
let rec gameLoop update fps = async {
do update ()
do! Async.Sleep (1000 / fps)
return! gameLoop update fps }
関数型言語いろいろ
有名どころ
• Haskell −  いわゆる純粋関数型
• OCaml −  ML ベース
• Scala −  JVM, マルチパラダイム
• Erlang −  どちらかといえば分散指向
• Clojure −  JVM,LISP 方言
まとめ
• 関数プログラミング
• F# での関数プログラミング
• 話さなかったこと 1:静的型付け関数型
• 話さなかったこと 2:コンビネータ

F#で学ぶ関数プログラミング入門?