SlideShare a Scribd company logo
函数プログラミングの集い2011
    チュートリゕル
   「モナドについて」
 株式会社 Preffered Infrastructure
       田中 英行
   tanaka.hideyuki@gmail.com
自己紹介
• 田中英行 (@tanakh, id:tanakh)
• 株式会社 Preferred Infrastructure (PFI) 勤務
    – 検索エンジンのゕルゴリズムとか作ってます
•   Haskell (2004~)
•   C++ (1998~)
•   BASIC (1992~)
•   プログラミングコンテスト愛好家
    – ICPC, ICFPC, CodeJam, TopCoder, …
本日の概要
• モナドとは?
• モナドの使い方
 – モナドのセマンテゖクス
 – 典型的なモナドの例
 – Haskellでのモナド
• モナドの作り方
 – モナドの゗ンスタンスに
 – モナド変換子
What is Monad?

モナドとは?
モナドとは何か?
• 非常に難しい質問です
• 既に数多くの人がそれに答えようとして
  います
 – そして各々が一見全く違う主張をしている
幾つかの例
『モナドは象である』
『モナドはメタフゔーではない』
『プログラマブル・コンテナ』
『コンベゕのゕナロジー』




        from “All About Monads”
いろいろありますが…
• 結局モナドとはなんなのか?




             モナドの力の秘密、
             いつか解き明かしてみたいな…
モナドについての疑問
• 疑問にもいろいろある
 – モナドとは何か?
 – 何の役に立つのか?
 – なぜモナドなのか?
   モナドがもてはやされるのか?
  • ゕローとモナド、どうして差がついた…
• それぞれについて、私なりの見解
モナドとは何なのか?
• モナドとはパラダ゗ムである !
抽象的な話
パラダ゗ム?
• プログラミングパラダ゗ム
 – 手続き型
 – 関数型
 – 論理型
 – オブジェクト志向

 – モナデゖック(?)
  • ここじゃない
モナドとは手続き型パラダ゗ムの
    再定義である
• プログラミングパラダ゗ム
 – 手続き型
  • モナデゖック
 – 関数型
 – 論理型
 – オブジェクト志向
意味的側面からの
    モナドのメタフゔー
• モナドは『プログラマブルセミコロン』
  である
Programmable Semicolon
• Real World Haskell より
手続き型言語と構造化定理
• プログラムは、「順次・反復・分岐」の
  基本的な構造の組み合わせによって記述
  できる
• これらはモナドへ直接的にマッピングで
  きる
それで、何が嬉しいの?
• 分岐のセマンテゖクス書き換え
• 反復のセマンテゖクス書き換え
 – そういうことができる言語は過去にはあった
• 逐次のセマンテゖクス書き換え
 – かつて無いもの(…の様な気がします)!
逐次のセマンテゖクス
• およそほとんどの手続き型言語では、
  セミコロンの意味は変えられない
 – 空気のような存在
• セミコロンの意味を変えることの意義が
  伝統的に見逃されて来たのではないか?
 int main()
 {                 main =
   foo(); bar();     foo >> bar
 }
継続との関係
• モナドは継続(continuation)の一般化とも考
  えることができます
• 継続=各セミコロンにおけるプログラム
  の状態
• モナドはセミコロンを記述するわけなの
  で、その状態を取り出すことは簡単
 – 実際に継続モナドというものがあります
セミコロンをいじることにより
     可能になること
• 普通のプログラムを非決定計算に変える
• 普通のプログラムにエラーハンドリング
  を(プログラムを書き換えずに)追加する
• 普通のプログラムに暗黙の状態を導入す
  る
コンテクスト
• 具体的なモナドに対して、それが計算に
  付加価値を与えます。それを(計算の)
  コンテクストと呼ぶことにします
 – つまり、モナドというのはコンテクスト付き
   の計算ということができる
• 例えば…
 – monad:リストモナド → ctx:非決定性
 – monad:Stateモナド → ctx:mutableな状態
 – etc …
それぞれにそういうプログラムを
書けばいいんじゃないんですか?
• コンテクストごとに異なる記法
• コンテクストごとに異なるプログラム
• コンテクストごとに異なる語彙
 ・・・



         抽象化の欠如
コンテクストの抽象化
• 共通のゕルゴリズムの記述
• 共通のコード片の抽象化




     よりメタレベルの抽象化へ
床下配線のゕナロジー
• モナドによるセミコロンの抽象化は
  床下配線と例えられることも
 – 見えないところを書き換える
少し具体的な話
例
• N-ク゗ーン問題
 – Int が与えられて解を返す
 – 解とはなんぞや?
  • 全解列挙
  • どれか一つを見つける
  • 一番いい解を頼む
 – いろいろ考えうる
N-Queen問題
• モナデゖックに書くと、これらを統一的
  に扱える
 – 解の列挙のストラテジをモナドとして記述
 – 問題を解くゕルゴリズムからの分離
前半まとめ
• モナドとは何なのか?
 – 計算コンテクストの抽象化である
• なんでそれが嬉しいの?
 – 具体的なコンテクストに依存しないコードを
   書ける
 – 抽象化したものを具体的なコードにできる
• なぜモナドなの?
 – モナドは構造化定理に必要な要素を自然に記
   述できて、なおかつ簡潔であるから
三行で言うと

• モナドは関数レベルで
 • メタプログラミング
 • するためのものです



  (´・_・`)えっ…?
How to use Monads

モナド入門・モナドの使い方
実装レベルのお話
モナドとは
• “ある特定の方法”で組み合わせることので
  きる計算のことをまとめて、


      モナド
と呼びます。
ちなみに
• 組み合わせ可能な計算はモナドだけではあり
  ません
 – いろいろな抽象化におけるそれが存在
• 例えば、
 –   関数 (関数合成)
 –   フゔンクタ (関手)
 –   ゕプリカテゖブ・フゔンクタ
 –   ゕロー
 –   Iteratee
 –   etc…
ひとまず置いておいて、
Haskellでのモナドのお話
Haskellでのモナド
• 次のような型クラス




これの゗ンスタンスが具体的なモナド=
計算コンテクスト
モナドになっている標準データ型

• 標準データ型の中にもモナドがある
 – リスト
 – Maybe
 – Either
 – IO
モナド則の必要性
• モナド則は、モナドを安全に組み合わせ
  るのに必要
 – これらの挙動が同じでなければ、組み合わせ
   方によって意味が変わるということになる
Haskellのdo記法
• Haskellではモナドを非常によく使うので、
  専用の構文糖衣が用意されています
高度なモナドの使い方
リストモナド
• リストはモナドにできる
• リストは非決定
  計算のコンテクスト
  と捉えることが
  できる
Maybeモナド
• Maybeもモナド
• 失敗するかもしれない計算
IOモナド
• 入出力を行う可能性のある計算
• HaskellではIOモナドを介してしか入出力を
  扱えない
IOモナドの功罪
• モナドに関するよくある誤解
 – モナドってpurely functional languageでIOする
   ためにあるんでしょ?


• モナドはIOのためにあるのではありません
• モナドはIOのためにあるのではありません
 – 大事なことなので
モナド則
• すべてのモナドは次のモナド則を満たす
  ”べき”である
 – 満たす保証をするのはプログラマの責任
 – あえて満たさなくても良い
モナド変換子(Monad Transformers)

• モナドとモナドを組み合わせるもの
 – (cf. 計算と計算を組み合わせるものがモナド)
動機
• 複数の計算コンテクストを合成したい
 – 失敗するかもしれないIO計算
 – エラーハンドリングできるパーザー
 – etc, …
MTL (Monad Transformer Library)
• 標準のモナドラ゗ブラリ
 – Preludeのモナドを大幅強化
• これらのものを含む
 – 幾つかの標準的なモナド
 – これらのモナドを合成するための
   モナド変換子(Monad Transformers)
MTLに含まれるモナド
•   Monad.Cont (継続)
•   Monad.Reader (ReadOnly状態)
•   Monad.Writer (ログ出力)
•   Monad.State (Mutable状態)
•   Monad.List (非決定計算)
•   Monad.Error (エラーハンドリング)

• これに加え、それぞれのモナド変換子版
モナド変換子
• 2つのモナドを合成するためのもの
• 例えばStateモナドの場合:
 – StateT s m a
    • モナド変換子版Stateモナド
    • State s a と比べて、mというパラメータが追加
    • mに合成したいモナドを代入
 – StateT s IO a
    • IOモナドを内包したStateモナド
    • IOモナドの操作とStateモナドの操作が両方できる
持ち上げ(lift)
• StateT s IO の例




  – StateT s IO の中でIOを行うには、持ち上げ(lift)
    を行う必要がある(型が合わないので)
モナドクラス
• 例えばIOを行うだけの計算

• これは、StateT s IO 以外のモナドでも使え
  て欲しい
 – ErrorT err IO
 – ReaderT s IO
 –…
MonadIOクラス
• そのために、IOをliftできるクラス全体を抽象
  化したMonadIOクラスを定義


• 先のコードは次のような型に


• StateT s IO などをMonadIOの゗ンスタンスに
  すれば使用可能に。
一般の持ち上げ
• モナド変換子に渡されるモナドはIOだけで
  はない
 – ネストする場合もある
• 一般ケースのために、MonadTransという
  クラスが用意されている


 – 内側のモナド外側のモナドに持ち上げること
   ができる
中盤まとめ
• モナドとは >>= と return の2つの演算が定
  義されたもの
• 標準データ型の多くのものがモナドに
  なっている
• mtlというモナド変換子ラ゗ブラリがある
• モナド変換子を用いてモナドを組み合わ
  せる
• モナド持ち上げで型の異なるモナドを張
  り合わせる
Advanced Topics
monad-control (1)
• liftの逆をするもの
• 動機
 – Haskellの例外ハンドリング機構はIOモナド
   ベース
 – 渡せるものがIO固定
   • MonadIO に対しても例外ハンドルしたい
monad-control (2)
• MonadIOに対して一般化




• それを行えるようにするために、
  MonadControlIOというクラスを用意
モナドいろいろ
• 近年実に様々なラ゗ブラリがモナデゖッ
  クラ゗ブラリとして提供されるようにな
  りました
• それらの一部を紹介していきたいと思い
  ます
MonadPar
• 並列計算を記述するためのモナド
 – `par`, `seq` などをモナド化したもの
Parser
• パーザいろいろ
 – Parsec, Attoparsec, trifecta
WebApp
• WAI, Yesod, Snap, CGI, …
Interpreter
• hint, BASIC, …
How to design your monads

モナドの作り方
モナドを設計するにあたって
• 自分のラ゗ブラリが、モナドとして抽象
  化できることに気づいたとします
• しかし、モナドの作り方を間違うと、非
  常に使い勝手の悪いものができてしまい
  ます
 – 使い勝手のよいモナドの実装には気をつける
   べきことが沢山あります
• ここまで紹介したことはすべて理解して
  おくことが望ましいです
1) 既存のモナドが利用できないか

• 実際のところ、mtlに含まれるモナドで、
  ほとんどのケースはカバーされます
• 作りたい計算が、mtlにあるモナドの組み
  合わせで実現できないかまず検討するべ
  きです
2) モナド変換子版を用意する
• いざモナドを作るとなったら、(原理的に)
  可能なのであれば、モナド変換子版を必
  ず用意しましょう
 – モナド変換子にはHogeTと、末尾に大文字Tを
   つけるのが慣習です
• 非モナド変換子版は、モナド変換子版に
  Identityモナドを代入したものにします
 – 実装を重複させてはいけません
MonadIOクラスの゗ンスタンスにする

• あなたのモナドをMonadIOの゗ンスタンス
  にしておくのはとても良いことです
• あなたのモナドを利用するすべての場所
  でIOを行うことができるようになります
• MonadIOを用意しておくのはモナドによっ
  てIOを行うHaskellにとっては極めて重要な
  ことです
※ IOモナドについて(1)
• IOモナドは、Haskellのプログラムの中では外
  すことのできないモナドです
 – unsafePerformIO などを除いて
• その結果、IOを呼ぶコードはそれ自身がIOを
  行わなくても、IOモナドにする必要がありま
  す
• Haskellによくある批判として、まともなプロ
  グラムを書いているとほとんどすべての関数
  の型がIOになる、というのがあります
 – IOモナドは感染するとか言われます
※ IOモナドについて(2)
• そこでMonadIOの出番です
• IOが必要なコンテクストについてのみ、
  MonadIOを要求させておけば良くなります
• Pureなモナドに関しては、具体的な型が決
  定するに従って、自動で持ち上げられる
  ことになります
• つまり、PureなコードとIOのコードのオー
  バーロードが可能になるということです
3) MonadControlIOの
      ゗ンスタンスにする
• あなたのモナドが例外を正しく扱えるよ
  うにするために、MonadControlIOの゗ンス
  タンスにしましょう
 – これがないと bracket などが正しく後処理でき
   ません
4) MonadTransの゗ンスタンスにする
• あなたのモナド変換子が、他のモナドを
  自動多段持ち上げ可能になるように(可能
  であれば)必ず、MonadTransの゗ンスタン
  スにしましょう
5) Functor, Applicative
         の゗ンスタンスにする
• Applicativeスタ゗ルというものがあります
 – http://d.hatena.ne.jp/kazu-yamamoto/20101211/1292021817
 – などを参照

• あなたのモナドをFunctor, Applicativeの゗
  ンスタンスにすると、使い勝手が大幅に
  向上します
• 必ずこれらの゗ンスタンスにしましょう
 – Monadの゗ンスタンスは必ずFunctor及び
   Applicativeの゗ンスタンスにできます
6) 必要に応じて、その他
• その他のモナドクラスの゗ンスタンスに
  します
 – エラーハンドリングを付けたいなら、
   MonadError
 – 失敗に対する代替を与えたいときには、
   Alternative
※ Alternativeクラスについて
• m1 <|> m2 なる演算子が定義されている
• m1が失敗したとき、m2の結果

• Alternativeの任意の゗ンスタンスに対して
 – many p – pを失敗するまで繰り返し
 – some p – pを失敗するまで1回以上繰り返し
 – optional p – p が失敗したらNothing成功したら
   Just aを返す
 – これらを定義することができる
GenericNewtypeDeriving
• 自分のモナドをこれらすべての゗ンスタ
  ンスにするのは骨の折れる作業です
• モナドがnewtypeの時、これをderiving で
  済ませることができます
 – -XGenericNewtypeDeriving 言語拡張
後半まとめ
• モナドを作るにあたって
 – MTLのモナドの組み合わせで実現できないか
   考える
 – いろいろなクラスの゗ンスタンスにしておく
 – モナド以外の有用なクラスが標準にあるので
   それの゗ンスタンスにもする

More Related Content

PPTX
純粋関数型アルゴリズム入門
PDF
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
PDF
線形計画法入門
PDF
Constexpr 中3女子テクニック
PDF
グラフニューラルネットワークとグラフ組合せ問題
PDF
ガウス過程入門
PDF
20分くらいでわかった気分になれるC++20コルーチン
PDF
Juliaで並列計算
純粋関数型アルゴリズム入門
constexpr関数はコンパイル時処理。これはいい。実行時が霞んで見える。cpuの嬌声が聞こえてきそうだ
線形計画法入門
Constexpr 中3女子テクニック
グラフニューラルネットワークとグラフ組合せ問題
ガウス過程入門
20分くらいでわかった気分になれるC++20コルーチン
Juliaで並列計算

What's hot (20)

PDF
画像認識の初歩、SIFT,SURF特徴量
PDF
プログラミングコンテストでの動的計画法
PDF
指数時間アルゴリズム入門
PDF
SAT/SMTソルバの仕組み
PDF
グラフニューラルネットワーク入門
PDF
Domain Modeling Made Functional (DevTernity 2022)
PDF
Freer Monads, More Extensible Effects
PDF
ZDD入門-お姉さんを救う方法
PDF
構造方程式モデルによる因果探索と非ガウス性
PDF
ゲーム開発者のための C++11/C++14
PPTX
ホモトピー型理論入門
 
PDF
Statistical Semantic入門 ~分布仮説からword2vecまで~
PDF
Stanコードの書き方 中級編
PDF
3次元レジストレーションの基礎とOpen3Dを用いた3次元点群処理
PDF
ニューラルネットワークを用いた自然言語処理
PDF
Transformer メタサーベイ
PPTX
[DL輪読会]Flow-based Deep Generative Models
PDF
CVIM#11 3. 最小化のための数値計算
PDF
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
PPTX
Gstreamer Basics
画像認識の初歩、SIFT,SURF特徴量
プログラミングコンテストでの動的計画法
指数時間アルゴリズム入門
SAT/SMTソルバの仕組み
グラフニューラルネットワーク入門
Domain Modeling Made Functional (DevTernity 2022)
Freer Monads, More Extensible Effects
ZDD入門-お姉さんを救う方法
構造方程式モデルによる因果探索と非ガウス性
ゲーム開発者のための C++11/C++14
ホモトピー型理論入門
 
Statistical Semantic入門 ~分布仮説からword2vecまで~
Stanコードの書き方 中級編
3次元レジストレーションの基礎とOpen3Dを用いた3次元点群処理
ニューラルネットワークを用いた自然言語処理
Transformer メタサーベイ
[DL輪読会]Flow-based Deep Generative Models
CVIM#11 3. 最小化のための数値計算
Pythonの処理系はどのように実装され,どのように動いているのか? 我々はその実態を調査すべくアマゾンへと飛んだ.
Gstreamer Basics
Ad

Similar to Monad tutorial (20)

PDF
MP in Haskell
PDF
並行プログラミングと継続モナド
KEY
Haskell Day2012 - 参照透過性とは何だったのか
PDF
モナドハンズオン前座
PDF
モナドをつくろう
PDF
オブジェクト指向開発におけるObject-Functional Programming
PDF
これから Haskell を書くにあたって
PDF
An engineer uses monads
PDF
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
KEY
モナドがいっぱい!
ODP
これから Haskell を書くにあたって
PDF
Monadなんてどうってことなかった話 - Monadなんてただの型クラス!
PDF
2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad
PDF
Object-Funcational Analysis and design
PDF
ScalaプログラマのためのHaskell入門
PDF
MP in Scala
PDF
Scalaプログラミング・マニアックス
KEY
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
PDF
Object-Functional Analysis and Design and Programming温泉
PDF
“Adoption and Focus: Practical Linear Types for Imperative Programming”他の紹介@P...
MP in Haskell
並行プログラミングと継続モナド
Haskell Day2012 - 参照透過性とは何だったのか
モナドハンズオン前座
モナドをつくろう
オブジェクト指向開発におけるObject-Functional Programming
これから Haskell を書くにあたって
An engineer uses monads
Monadic Programmingのススメ - Functional Reactive Programmingへのアプローチ
モナドがいっぱい!
これから Haskell を書くにあたって
Monadなんてどうってことなかった話 - Monadなんてただの型クラス!
2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad
Object-Funcational Analysis and design
ScalaプログラマのためのHaskell入門
MP in Scala
Scalaプログラミング・マニアックス
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
Object-Functional Analysis and Design and Programming温泉
“Adoption and Focus: Practical Linear Types for Imperative Programming”他の紹介@P...
Ad

More from Hideyuki Tanaka (8)

PDF
ESPM2 2018 - Automatic Generation of High-Order Finite-Difference Code with T...
PDF
Xpath in-lens
PPTX
IdrisでWebアプリを書く
PDF
手書きスライド
PPTX
Yesod勉強会
PDF
C++コミュニティーの中心でC++をDISる
PDF
関数プログラミング入門
PPTX
Icfp2009
ESPM2 2018 - Automatic Generation of High-Order Finite-Difference Code with T...
Xpath in-lens
IdrisでWebアプリを書く
手書きスライド
Yesod勉強会
C++コミュニティーの中心でC++をDISる
関数プログラミング入門
Icfp2009

Monad tutorial