monad tutorial
DESCRIPTION
TRANSCRIPT
![Page 1: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/1.jpg)
函数プログラミングの集い2011 チュートリゕル
「モナドについて」
株式会社 Preffered Infrastructure
田中 英行
![Page 2: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/2.jpg)
自己紹介
• 田中英行 (@tanakh, id:tanakh)
• 株式会社 Preferred Infrastructure (PFI) 勤務 –検索エンジンのゕルゴリズムとか作ってます
• Haskell (2004~)
• C++ (1998~)
• BASIC (1992~)
• プログラミングコンテスト愛好家 – ICPC, ICFPC, CodeJam, TopCoder, …
![Page 3: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/3.jpg)
本日の概要
• モナドとは?
• モナドの使い方
–モナドのセマンテゖクス
–典型的なモナドの例
– Haskellでのモナド
• モナドの作り方
–モナドのンスタンスに
–モナド変換子
![Page 4: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/4.jpg)
モナドとは? What is Monad?
![Page 5: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/5.jpg)
モナドとは何か?
• 非常に難しい質問です
• 既に数多くの人がそれに答えようとしています
–そして各々が一見全く違う主張をしている
![Page 6: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/6.jpg)
幾つかの例
![Page 7: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/7.jpg)
『モナドは象である』
![Page 8: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/8.jpg)
『モナドはメタフゔーではない』
![Page 9: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/9.jpg)
『プログラマブル・コンテナ』
![Page 10: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/10.jpg)
『コンベゕのゕナロジー』
from “All About Monads”
![Page 11: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/11.jpg)
いろいろありますが…
• 結局モナドとはなんなのか?
モナドの力の秘密、 いつか解き明かしてみたいな…
![Page 12: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/12.jpg)
モナドについての疑問
• 疑問にもいろいろある
–モナドとは何か?
–何の役に立つのか?
–なぜモナドなのか? モナドがもてはやされるのか?
• ゕローとモナド、どうして差がついた…
• それぞれについて、私なりの見解
![Page 13: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/13.jpg)
モナドとは何なのか?
• モナドとはパラダムである !
![Page 14: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/14.jpg)
抽象的な話
![Page 15: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/15.jpg)
パラダム?
• プログラミングパラダム
–手続き型
–関数型
–論理型
–オブジェクト志向
–モナデゖック(?)
• ここじゃない
![Page 16: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/16.jpg)
モナドとは手続き型パラダムの再定義である
• プログラミングパラダム
–手続き型
• モナデゖック
–関数型
–論理型
–オブジェクト志向
![Page 17: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/17.jpg)
意味的側面からの モナドのメタフゔー
• モナドは『プログラマブルセミコロン』である
![Page 18: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/18.jpg)
Programmable Semicolon
• Real World Haskell より
![Page 19: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/19.jpg)
手続き型言語と構造化定理
• プログラムは、「順次・反復・分岐」の基本的な構造の組み合わせによって記述できる
• これらはモナドへ直接的にマッピングできる
![Page 20: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/20.jpg)
それで、何が嬉しいの?
• 分岐のセマンテゖクス書き換え
• 反復のセマンテゖクス書き換え
–そういうことができる言語は過去にはあった
• 逐次のセマンテゖクス書き換え
–かつて無いもの(…の様な気がします)!
![Page 21: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/21.jpg)
逐次のセマンテゖクス
• およそほとんどの手続き型言語では、 セミコロンの意味は変えられない
–空気のような存在
• セミコロンの意味を変えることの意義が 伝統的に見逃されて来たのではないか?
int main() { foo(); bar(); }
main = foo >> bar
![Page 22: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/22.jpg)
継続との関係
• モナドは継続(continuation)の一般化とも考えることができます
• 継続=各セミコロンにおけるプログラムの状態
• モナドはセミコロンを記述するわけなので、その状態を取り出すことは簡単
–実際に継続モナドというものがあります
![Page 23: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/23.jpg)
セミコロンをいじることにより 可能になること
• 普通のプログラムを非決定計算に変える
• 普通のプログラムにエラーハンドリングを(プログラムを書き換えずに)追加する
• 普通のプログラムに暗黙の状態を導入する
![Page 24: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/24.jpg)
コンテクスト
• 具体的なモナドに対して、それが計算に付加価値を与えます。それを(計算の)コンテクストと呼ぶことにします –つまり、モナドというのはコンテクスト付きの計算ということができる
• 例えば… – monad:リストモナド → ctx:非決定性
– monad:Stateモナド → ctx:mutableな状態
– etc …
![Page 25: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/25.jpg)
それぞれにそういうプログラムを 書けばいいんじゃないんですか?
• コンテクストごとに異なる記法
• コンテクストごとに異なるプログラム
• コンテクストごとに異なる語彙
・・・
抽象化の欠如
![Page 26: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/26.jpg)
コンテクストの抽象化
• 共通のゕルゴリズムの記述
• 共通のコード片の抽象化
よりメタレベルの抽象化へ
![Page 27: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/27.jpg)
床下配線のゕナロジー
• モナドによるセミコロンの抽象化は 床下配線と例えられることも
–見えないところを書き換える
![Page 28: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/28.jpg)
少し具体的な話
![Page 29: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/29.jpg)
例
• N-クーン問題
– Int が与えられて解を返す
–解とはなんぞや?
• 全解列挙
• どれか一つを見つける
• 一番いい解を頼む
–いろいろ考えうる
![Page 30: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/30.jpg)
N-Queen問題
• モナデゖックに書くと、これらを統一的に扱える
–解の列挙のストラテジをモナドとして記述
–問題を解くゕルゴリズムからの分離
![Page 31: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/31.jpg)
前半まとめ
• モナドとは何なのか? –計算コンテクストの抽象化である
• なんでそれが嬉しいの? –具体的なコンテクストに依存しないコードを書ける
–抽象化したものを具体的なコードにできる
• なぜモナドなの? –モナドは構造化定理に必要な要素を自然に記述できて、なおかつ簡潔であるから
![Page 32: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/32.jpg)
三行で言うと
• モナドは関数レベルで
• メタプログラミング
• するためのものです
(´・_・`)えっ…?
![Page 33: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/33.jpg)
モナド入門・モナドの使い方 How to use Monads
![Page 34: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/34.jpg)
実装レベルのお話
![Page 35: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/35.jpg)
モナドとは
• “ある特定の方法”で組み合わせることのできる計算のことをまとめて、
と呼びます。
モナド
![Page 36: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/36.jpg)
ちなみに
• 組み合わせ可能な計算はモナドだけではありません – いろいろな抽象化におけるそれが存在
• 例えば、 – 関数 (関数合成)
– フゔンクタ (関手)
– ゕプリカテゖブ・フゔンクタ
– ゕロー
– Iteratee
– etc…
![Page 37: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/37.jpg)
ひとまず置いておいて、 Haskellでのモナドのお話
![Page 38: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/38.jpg)
Haskellでのモナド
• 次のような型クラス
これのンスタンスが具体的なモナド=計算コンテクスト
![Page 39: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/39.jpg)
モナドになっている標準データ型
• 標準データ型の中にもモナドがある
–リスト
– Maybe
– Either
– IO
![Page 40: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/40.jpg)
モナド則の必要性
• モナド則は、モナドを安全に組み合わせるのに必要
–これらの挙動が同じでなければ、組み合わせ方によって意味が変わるということになる
![Page 41: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/41.jpg)
Haskellのdo記法
• Haskellではモナドを非常によく使うので、専用の構文糖衣が用意されています
![Page 42: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/42.jpg)
高度なモナドの使い方
![Page 43: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/43.jpg)
リストモナド
• リストはモナドにできる
• リストは非決定 計算のコンテクスト と捉えることが できる
![Page 44: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/44.jpg)
Maybeモナド
• Maybeもモナド
• 失敗するかもしれない計算
![Page 45: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/45.jpg)
IOモナド
• 入出力を行う可能性のある計算
• HaskellではIOモナドを介してしか入出力を扱えない
![Page 46: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/46.jpg)
IOモナドの功罪
• モナドに関するよくある誤解
–モナドってpurely functional languageでIOするためにあるんでしょ?
• モナドはIOのためにあるのではありません
• モナドはIOのためにあるのではありません
–大事なことなので
![Page 47: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/47.jpg)
モナド則
• すべてのモナドは次のモナド則を満たす ”べき”である
–満たす保証をするのはプログラマの責任
–あえて満たさなくても良い
![Page 48: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/48.jpg)
モナド変換子(Monad Transformers)
• モナドとモナドを組み合わせるもの
– (cf. 計算と計算を組み合わせるものがモナド)
![Page 49: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/49.jpg)
動機
• 複数の計算コンテクストを合成したい
–失敗するかもしれないIO計算
–エラーハンドリングできるパーザー
– etc, …
![Page 50: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/50.jpg)
MTL (Monad Transformer Library)
• 標準のモナドラブラリ
– Preludeのモナドを大幅強化
• これらのものを含む
–幾つかの標準的なモナド
–これらのモナドを合成するための モナド変換子(Monad Transformers)
![Page 51: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/51.jpg)
MTLに含まれるモナド
• Monad.Cont (継続)
• Monad.Reader (ReadOnly状態)
• Monad.Writer (ログ出力)
• Monad.State (Mutable状態)
• Monad.List (非決定計算)
• Monad.Error (エラーハンドリング)
• これに加え、それぞれのモナド変換子版
![Page 52: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/52.jpg)
モナド変換子
• 2つのモナドを合成するためのもの
• 例えばStateモナドの場合:
– StateT s m a • モナド変換子版Stateモナド
• State s a と比べて、mというパラメータが追加
• mに合成したいモナドを代入
– StateT s IO a • IOモナドを内包したStateモナド
• IOモナドの操作とStateモナドの操作が両方できる
![Page 53: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/53.jpg)
持ち上げ(lift)
• StateT s IO の例
– StateT s IO の中でIOを行うには、持ち上げ(lift)を行う必要がある(型が合わないので)
![Page 54: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/54.jpg)
モナドクラス
• 例えばIOを行うだけの計算
• これは、StateT s IO 以外のモナドでも使えて欲しい
– ErrorT err IO
– ReaderT s IO
– …
![Page 55: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/55.jpg)
MonadIOクラス
• そのために、IOをliftできるクラス全体を抽象化したMonadIOクラスを定義
• 先のコードは次のような型に
• StateT s IO などをMonadIOのンスタンスにすれば使用可能に。
![Page 56: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/56.jpg)
一般の持ち上げ
• モナド変換子に渡されるモナドはIOだけではない –ネストする場合もある
• 一般ケースのために、MonadTransというクラスが用意されている
–内側のモナド外側のモナドに持ち上げることができる
![Page 57: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/57.jpg)
中盤まとめ
• モナドとは >>= と return の2つの演算が定義されたもの
• 標準データ型の多くのものがモナドになっている
• mtlというモナド変換子ラブラリがある
• モナド変換子を用いてモナドを組み合わせる
• モナド持ち上げで型の異なるモナドを張り合わせる
![Page 58: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/58.jpg)
Advanced Topics
![Page 59: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/59.jpg)
monad-control (1)
• liftの逆をするもの
• 動機
– Haskellの例外ハンドリング機構はIOモナドベース
–渡せるものがIO固定
• MonadIO に対しても例外ハンドルしたい
![Page 60: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/60.jpg)
monad-control (2)
• MonadIOに対して一般化
• それを行えるようにするために、MonadControlIOというクラスを用意
![Page 61: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/61.jpg)
モナドいろいろ
• 近年実に様々なラブラリがモナデゖックラブラリとして提供されるようになりました
• それらの一部を紹介していきたいと思います
![Page 62: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/62.jpg)
MonadPar
• 並列計算を記述するためのモナド
– `par`, `seq` などをモナド化したもの
![Page 63: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/63.jpg)
Parser
• パーザいろいろ
– Parsec, Attoparsec, trifecta
![Page 64: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/64.jpg)
WebApp
• WAI, Yesod, Snap, CGI, …
![Page 65: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/65.jpg)
Interpreter
• hint, BASIC, …
![Page 66: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/66.jpg)
モナドの作り方 How to design your monads
![Page 67: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/67.jpg)
モナドを設計するにあたって
• 自分のラブラリが、モナドとして抽象化できることに気づいたとします
• しかし、モナドの作り方を間違うと、非常に使い勝手の悪いものができてしまいます –使い勝手のよいモナドの実装には気をつけるべきことが沢山あります
• ここまで紹介したことはすべて理解しておくことが望ましいです
![Page 68: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/68.jpg)
1) 既存のモナドが利用できないか
• 実際のところ、mtlに含まれるモナドで、ほとんどのケースはカバーされます
• 作りたい計算が、mtlにあるモナドの組み合わせで実現できないかまず検討するべきです
![Page 69: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/69.jpg)
2) モナド変換子版を用意する
• いざモナドを作るとなったら、(原理的に)可能なのであれば、モナド変換子版を必ず用意しましょう
–モナド変換子にはHogeTと、末尾に大文字Tをつけるのが慣習です
• 非モナド変換子版は、モナド変換子版にIdentityモナドを代入したものにします
–実装を重複させてはいけません
![Page 70: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/70.jpg)
MonadIOクラスのンスタンスにする
• あなたのモナドをMonadIOのンスタンスにしておくのはとても良いことです
• あなたのモナドを利用するすべての場所でIOを行うことができるようになります
• MonadIOを用意しておくのはモナドによってIOを行うHaskellにとっては極めて重要なことです
![Page 71: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/71.jpg)
※ IOモナドについて(1)
• IOモナドは、Haskellのプログラムの中では外すことのできないモナドです – unsafePerformIO などを除いて
• その結果、IOを呼ぶコードはそれ自身がIOを行わなくても、IOモナドにする必要があります
• Haskellによくある批判として、まともなプログラムを書いているとほとんどすべての関数の型がIOになる、というのがあります – IOモナドは感染するとか言われます
![Page 72: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/72.jpg)
※ IOモナドについて(2)
• そこでMonadIOの出番です
• IOが必要なコンテクストについてのみ、MonadIOを要求させておけば良くなります
• Pureなモナドに関しては、具体的な型が決定するに従って、自動で持ち上げられることになります
• つまり、PureなコードとIOのコードのオーバーロードが可能になるということです
![Page 73: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/73.jpg)
3) MonadControlIOの ンスタンスにする
• あなたのモナドが例外を正しく扱えるようにするために、MonadControlIOのンスタンスにしましょう
–これがないと bracket などが正しく後処理できません
![Page 74: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/74.jpg)
4) MonadTransのンスタンスにする
• あなたのモナド変換子が、他のモナドを自動多段持ち上げ可能になるように(可能であれば)必ず、MonadTransのンスタンスにしましょう
![Page 75: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/75.jpg)
5) Functor, Applicative のンスタンスにする
• Applicativeスタルというものがあります – http://d.hatena.ne.jp/kazu-yamamoto/20101211/1292021817
– などを参照
• あなたのモナドをFunctor, Applicativeのンスタンスにすると、使い勝手が大幅に向上します
• 必ずこれらのンスタンスにしましょう
– Monadのンスタンスは必ずFunctor及びApplicativeのンスタンスにできます
![Page 76: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/76.jpg)
6) 必要に応じて、その他
• その他のモナドクラスのンスタンスにします
–エラーハンドリングを付けたいなら、
MonadError
–失敗に対する代替を与えたいときには、
Alternative
![Page 77: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/77.jpg)
※ Alternativeクラスについて
• m1 <|> m2 なる演算子が定義されている
• m1が失敗したとき、m2の結果
• Alternativeの任意のンスタンスに対して – many p – pを失敗するまで繰り返し
– some p – pを失敗するまで1回以上繰り返し
– optional p – p が失敗したらNothing成功したらJust aを返す
–これらを定義することができる
![Page 78: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/78.jpg)
GenericNewtypeDeriving
• 自分のモナドをこれらすべてのンスタンスにするのは骨の折れる作業です
• モナドがnewtypeの時、これをderiving で済ませることができます
– -XGenericNewtypeDeriving 言語拡張
![Page 79: Monad tutorial](https://reader034.vdocuments.site/reader034/viewer/2022042601/5466968db4af9f623f8b5409/html5/thumbnails/79.jpg)
後半まとめ
• モナドを作るにあたって
– MTLのモナドの組み合わせで実現できないか考える
–いろいろなクラスのンスタンスにしておく
–モナド以外の有用なクラスが標準にあるのでそれのンスタンスにもする