SlideShare a Scribd company logo
F#による Functional Programming
           入門

            bleis-tift


        December 22 2012
自己紹介




id:bleis-tift / @bleis
鈴鹿高専電子情報工学科卒業生
Microsoft MVP for Visual F#
いきなりですが質問です




Q1. プログラミングしたことありますか?
Q2. どんな言語を使いましたか?

C, C++, BASIC, Java, C#, PHP, Perl, Python,
Ruby, JavaScript, ...
授業だと大体こんなところでしょうか?
今日話すこと



授業ではあまり取り上げられないであろうタイプ
の言語である、

  関数型プログラミング言語
を取り上げ、関数プログラミングについて紹介し
ます。
その前に・
            ・・

手続型言語ってなんでしょうか?
  手続きを記述する
    処理のまとまりを「手続き」としてまとめる
    手続きを構成するのは「文」が基本
  状態を書き換える
    基本的に変数は書き換え可能
    単純なループは変数の書き換えがほぼ必須


  手続型言語は文中心かつ、
  書き換え可能な変数が必須
手続型言語に対し・
             ・・

関数型言語はざっくりこんな感じです。
  関数を記述する
    処理のまとまりを「関数」としてまとめる
    関数を構成するのは「式」
  状態の書き換えは局所化する
    基本的に変数は書き換え不可能
    変数の書き換えによらない繰り返し


    関数型言語は式中心
式と文の違い




式と文の違い、分かりますか?
  式は評価することで値になる
  文そのものは値を持たない
値が書けるところには式が書ける!
式と文の違い (文)
Java
int[] f(int x) {
  int[] res = new int[x];
  for (int i = 0; i < x; i++)
    res[i] = i * 2;
  return res;
}
int sum(int[] xs) { ... }
// これはもちろん可能
int total = sum(f(10));
// これは出来ない
int total = sum(
  int[] res = new int[x];
  for (int i = 0; i < x; i++)
    res[i] = i * 2;
  return res;
);
式と文の違い (式)
F#
let f x =
  let res = Array.zeroCreate x
  for i in 0..(x - 1) do
    res.[i] <- i * 2
  res
let sum xs = ...
// これはもちろん可能
let total = sum(f 10)
// これも可能!
let total =
  sum (
    let res = Array.zeroCreate 10
    for i in 0..(10 - 1) do
      res.[i] <- i * 2
    res
  )
式中心であることの利点




式を組み合わせてより大きく
 複雑な式を構築できる!
F#について

ちょっと休憩して、F#について。
   Visual Studio に標準搭載されている、
   マルチパラダイム言語
   (コアとなるパラダイムは関数型)
   .NET Framework 上で動作するため、
   .NET の資産を活かせる
   強い静的型付き言語
   インデントを文法に含む (軽量構文の場合)
   オープンソース
さっきのコードをもう一回見てみる


let f x =
  let res = Array.zeroCreate x
  for i in 0..(x - 1) do
    res.[i] <- i * 2 // 状態書き換えてる!
  res

状態書き換えない版
let f x =
  Array.init x ((*)2)

ループを自分で書く必要すらない!
→バグの抑制につながる
F#って静的型付き言語って言ったよね・ ?
                  ・・


今までのコード、型書いてません。
でも、型推論によってコンパイル時に型が付いて
いたのです!
// int を受け取って int[] を返す関数
// 「int -> int[]」と記述する
let f x =
  Array.init x ((*)2)

この関数にどうやって型が付いたのか見ていき
ます。
その前に




((*)2)って何!
((*)2) について

F#では、中置演算子を関数として扱える
2 * 4   // 8
(*) 2 4 // 8

そして、複数引数の関数に引数を「一部」与える
ことができる
let f x y = x * y
f 2 4 // 8
let g = f 2
g 4   // 8

つまり、((*)2) は「何かを 2 倍する関数」
型推論のステップ
    let f x =
      Array.init x ((*)2)

      1   Array.init は、int → (int → α) → α
                                         []
.     2   x は Array.init の第一引数として渡している
             x の型は int
      3   戻り値の型は Array.init の戻り値の型と同じ
.
             f の戻り値の型はα
                      []
      4   掛け算「*」の型は int → int → int
             ((*)2) は引数を一つ与えているので、int → int
             これを Array.init の第二引数として渡しているの
.            で、(int → α) のαは int

    全体として、f は「int → int ]
                      [ 」
型推論の利点




 型を書かなくても型が付く
→型チェックの恩恵が受けられる
ちょっと休憩




ここまでで何か質問ありますか?
ここからは型について



A か B か C のどれかを表す型が欲しくなったとき
どうしますか?
列挙型を使う?
Java の例
enum T { A, B, C }

これでどうや!
列挙型でダメな場合


列挙型は「A の時のみ必要な情報」を保持でき
ない
例えば、
   アンケートの項目「このイベントを何で知り
   ましたか?」
   Web サイト / Twitter / Facebook / その他
   その他の場合は理由が必要
これは列挙型ではうまくあらわせない・               ・・
どうしよう


列挙型とクラスでやる?
enum InfoSource {
  WebSite, Twitter, Facebook, Etc
}
class Answer {
  InfoSource source;
  String etc;
  ...
}
Etc 以外の時に etc が使われてしまうかもしれない
どうしよう・
                    ・・
クラス階層を作ってみる?
こうや!
interface InfoSource { }
enum WebSite implements InfoSource { Instance }
enum Twitter implements InfoSource { Instance }
enum Facebook implements InfoSource { Instance }
class Etc implements InfoSource {
  String etc;
}

    Etc 以外の時は etc が使えない!
    でも InfoSource を Etc として使うためには
    キャストが必要
    結局コンパイル時に解決できていない
    そこで Visitor ですよ!
Visitor
Visitor の導入
interface Visitor {
  void webSite(WebSite w);
  void twitter(Twitter t);
  void facebook(Facebook f);
  void etc(Etc e);
}
interface InfoSource { void accept(Visitor v); }
enum WebSite implements InfoSource {
  Instance;
  public void accept(Visitor v) { return v.webSite(this); }
}
enum Twitter implements InfoSource {
  Instance;
  public void accept(Visitor v) { return v.twitter(this); }
}
enum Facebook implements InfoSource {
  Instance;
  public void accept(Visitor v) { return v.facebook(this); }
}
class Etc implements InfoSource {
  String etc;
  public void accept(Visitor v) { return v.etc(this); }
}
やってられるかー!
そこで直和型ですよ!



F#の直和型 (判別共用体) を使えばこの通り
type InfoSource =
  | WebSite
  | Twitter
  | Facebook
  | Etc of string

すっきり!
使い方も簡単

match 式を使う
let toStr src =
  match src with
  | WebSite -> "Web サイト"
  | Twitter -> "Twitter"
  | Facebook -> "Facebook"
  | Etc etc -> "その他 (" + etc + ")"

function 式でも可
let toStr = function
| WebSite -> "Web サイト"
| Twitter -> "Twitter"
| Facebook -> "Facebook"
| Etc etc -> "その他 (" + etc + ")"
判別共用体のさらなる用途




ここまでは、列挙型に毛の生えたようなもの
ここまででも便利だが・
          ・・
判別共用体は、自分自身を参照することで更
に便利に!
情報系ではおそらく一度は実装する

二分木




これを実装してみましょう
二分木の実装

Java の場合
public class BinTree {
  final int value;
  BinTree left = null;
  BinTree right = null;
  public BinTree(int value) {
    this.value = value;
  }
}

F#の場合
type BinTree =
  | Leaf
  | Node of BinTree * int * BinTree
    //         ↑              ↑
二分探索木の探索
Java の場合
public boolean contains(int value) {
  if (value == this.value)
    return true;
  if (value < this.value && lelft != null)
    return left.contains(value);
  if (this.value < value && right != null)
    return right.contains(value);
  return false;
}

F#の場合
let rec contains   value = function
| Leaf -> false
| Node (l, v, r)   when v = value -> true
| Node (l, v, r)   when value < v -> contains value l
| Node (l, v, r)   when v < value -> contains value r
両者の違い



F#の実装の方が短い (Java よりも宣言的)
Java 版は null を使うため、
NullPointerException が起こりうるのに対し、
F#版は null を使わない
Java 版は二分木の操作は参照をやりくりする
必要があるのに対し、F#版はパターンマッ
チが使える
判別共用体は



再帰的なデータ構造を上手に扱える
  再帰的なデータ構造は思いのほか多い
  リスト、木、ファイルシステム、などなど
簡単に記述できる
  型を定義するハードルが低い (型が軽い)
取りこぼし




リストとリストの処理
高階関数 (関数が第一級の値)
少ないルールを組み合わせる
モナドとか
まとめ




文より式!
直和型 (判別共用体)!
F# ! F# !

More Related Content

PDF
Popcntによるハミング距離計算
PDF
プログラムの処方箋~健康なコードと病んだコード
PDF
F#入門 ~関数プログラミングとは何か~
PDF
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
PDF
いまさら聞けない!CUDA高速化入門
PDF
ゲーム開発者のための C++11/C++14
PDF
LLVM最適化のこつ
PDF
中3女子が狂える本当に気持ちのいい constexpr
Popcntによるハミング距離計算
プログラムの処方箋~健康なコードと病んだコード
F#入門 ~関数プログラミングとは何か~
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
いまさら聞けない!CUDA高速化入門
ゲーム開発者のための C++11/C++14
LLVM最適化のこつ
中3女子が狂える本当に気持ちのいい constexpr

What's hot (20)

PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
PDF
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
PDF
Pythonによる黒魔術入門
PDF
暗号技術の実装と数学
PPT
Glibc malloc internal
PDF
オブジェクト指向の設計と実装の学び方のコツ
PDF
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
PDF
1076: CUDAデバッグ・プロファイリング入門
PPTX
大規模分散システムの現在 -- Twitter
PDF
Webアプリを並行開発する際のマイグレーション戦略
PDF
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
PDF
Scala の関数型プログラミングを支える技術
PDF
オブジェクト指向エクササイズのススメ
PPTX
SQLチューニング入門 入門編
PDF
日本語テストメソッドについて
PDF
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
PDF
できる!並列・並行プログラミング
PDF
JenkinsとDockerって何が良いの? 〜言うてるオレもわからんわ〜 #jenkinsstudy
PPTX
SDL2の紹介
PDF
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
【Unite Tokyo 2018】さては非同期だなオメー!async/await完全に理解しよう
Pythonによる黒魔術入門
暗号技術の実装と数学
Glibc malloc internal
オブジェクト指向の設計と実装の学び方のコツ
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
1076: CUDAデバッグ・プロファイリング入門
大規模分散システムの現在 -- Twitter
Webアプリを並行開発する際のマイグレーション戦略
【Unite 2018 Tokyo】60fpsのその先へ!スマホの物量限界に挑んだSTG「アカとブルー」の開発設計
Scala の関数型プログラミングを支える技術
オブジェクト指向エクササイズのススメ
SQLチューニング入門 入門編
日本語テストメソッドについて
CUDAのアセンブリ言語基礎のまとめ PTXとSASSの概説
できる!並列・並行プログラミング
JenkinsとDockerって何が良いの? 〜言うてるオレもわからんわ〜 #jenkinsstudy
SDL2の紹介
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
Ad

Viewers also liked (20)

PDF
C#(VB)プログラマのためのF#入門
PDF
F#の基礎(?)
PDF
Better C#の脱却を目指して
PDF
async/await不要論
PDF
F#事例発表
PDF
関数型言語のすすめ
PDF
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
PDF
.NET系開発者から見たJava
PPTX
本になりました! ~ チーム開発の教科書 C#によるモダンな開発を実践しよう!
PPT
どこでも使えるF sharp again pub
PDF
VBAを書きたくない話(Excel-DNAの紹介)
PDF
ぼくのかんがえたさいきょうのLL
PDF
yieldとreturnの話
PDF
F#の基礎(嘘)
PDF
モナドハンズオン前座
PPTX
解説?FSharp.Quotations.Compiler
PPTX
Xamarin.forms実践投入してみて
PDF
論理と計算のしくみ 5.3 型付きλ計算 (前半)
PPTX
『ポイッとヒーロー』の unity5移行事例
PPTX
Unityでlinqを使おう
C#(VB)プログラマのためのF#入門
F#の基礎(?)
Better C#の脱却を目指して
async/await不要論
F#事例発表
関数型言語のすすめ
ラムダでウィザード 滅せよ手続き、とチャーチは言った (※言ってません)
.NET系開発者から見たJava
本になりました! ~ チーム開発の教科書 C#によるモダンな開発を実践しよう!
どこでも使えるF sharp again pub
VBAを書きたくない話(Excel-DNAの紹介)
ぼくのかんがえたさいきょうのLL
yieldとreturnの話
F#の基礎(嘘)
モナドハンズオン前座
解説?FSharp.Quotations.Compiler
Xamarin.forms実践投入してみて
論理と計算のしくみ 5.3 型付きλ計算 (前半)
『ポイッとヒーロー』の unity5移行事例
Unityでlinqを使おう
Ad

Similar to F#によるFunctional Programming入門 (20)

PDF
Swift らしい表現を目指そう #eventdots
PDF
関数型プログラミング入門 for Matlab ユーザー
PDF
ちょっと詳しくJavaScript 第2回【関数と引数】
PDF
Unity2015_No10_~UGUI&Audio~
PDF
Swift 2.0 で変わったところ「後編」 #cswift
PDF
JSX / Haxe / TypeScript
PDF
Go conference 2017 Lightning talk
PDF
たのしい関数型
PPTX
仕事でも Groovy を使おう!
PDF
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
PDF
これからの「言語」の話をしよう ―― 未来を生きるためのツール
PPT
言語処理系入門4
PPT
言語処理系入門3
PDF
Refactoring point of Kotlin application
PDF
Essential Scala 第5章 シーケンス処理
PDF
リテラルと型の話 #__swift__
PDF
LastaFluteでKotlinをはじめよう
PDF
Replace Output Iterator and Extend Range JP
PDF
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
PDF
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章
Swift らしい表現を目指そう #eventdots
関数型プログラミング入門 for Matlab ユーザー
ちょっと詳しくJavaScript 第2回【関数と引数】
Unity2015_No10_~UGUI&Audio~
Swift 2.0 で変わったところ「後編」 #cswift
JSX / Haxe / TypeScript
Go conference 2017 Lightning talk
たのしい関数型
仕事でも Groovy を使おう!
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
これからの「言語」の話をしよう ―― 未来を生きるためのツール
言語処理系入門4
言語処理系入門3
Refactoring point of Kotlin application
Essential Scala 第5章 シーケンス処理
リテラルと型の話 #__swift__
LastaFluteでKotlinをはじめよう
Replace Output Iterator and Extend Range JP
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第6回 ‟文字列とオブジェクト„
【Topotal輪読会】JavaScript で学ぶ関数型プログラミング 2 章

More from bleis tift (17)

PDF
PCさえあればいい。
PDF
No more Legacy documents
PDF
効果の低いテストの話
PDF
テストの自動化を考える前に
PDF
札束でExcelを殴る
PDF
SI屋のためのF# ~DSL編~
PDF
yield and return (poor English ver)
PDF
現実(えくせる)と戦う話
PDF
自分戦略
PDF
F#で始めるスマートフォンアプリ
PDF
SCMBC闇LT資料
PPTX
SCMBC Git入門セッション発表資料
PDF
輪るビングドラム.NET
PDF
仕事で使うF#
PDF
SCM Boot Camp
PDF
Vim再入門
PDF
CIのその先へ
PCさえあればいい。
No more Legacy documents
効果の低いテストの話
テストの自動化を考える前に
札束でExcelを殴る
SI屋のためのF# ~DSL編~
yield and return (poor English ver)
現実(えくせる)と戦う話
自分戦略
F#で始めるスマートフォンアプリ
SCMBC闇LT資料
SCMBC Git入門セッション発表資料
輪るビングドラム.NET
仕事で使うF#
SCM Boot Camp
Vim再入門
CIのその先へ

F#によるFunctional Programming入門