Haskell超初心者勉強会17
第14章 前半
2013/8/22
Thursday, August 22, 13
14章はモナドの紹介
•文脈の活用方法がわかるのか?
•紹介するモナドは mtl パッケージ内に
•ghc-pkg list ¦ grep mtl でインストー
ルされていることを確認
Thursday, August 22, 13
Writerモナド
•もう一つの値がくっついた値
•くっつく値はログのように振る舞う
•すべてのログが単一のログ値にまとま
ることを保証できる
Thursday, August 22, 13
ナイーブに実装してみる
isBigGang :: Int -> Bool
isBigGang x = x > 9
isBigGang :: Int -> (Bool, String)
isBigGang x =
(x > 9, "Compare...
すでに文字列(文脈)のくっ
ついた値を処理するには?
applyLog :: (a, String) ->
(a -> (b, String)) -> (b, String)
applyLog (x, log) f =
let (y, newL...
applyLogを使ってみる
•ログが連結される
•関数は文脈なしの値を引数にとる
> (3, "abc") `applyLog` isBigGang
(False, "abcCompared gang size to 9")
> ("Tobi...
モノイドが助けに来たよ
付加情報はStringにかぎらずリスト一般にできるよね。
++使ってるし。
applyLog :: (a,[c]) -> (a -> (b,[c]))
-> (b,[c])
付加情報としてByteStringも使いたい。...
モノイドを使って
書き換えてみる
applyLog :: (Monoid m) =>
(a,m)->(a->(b,m))->(b,m)
applyLog (x, log) f =
let (y, newLog) = f x in
(y, log...
食べ物を与えると
飲み物+値段が返る関数
import Data.Monoid
type Food = String
type Price = Sum Int
addDrink :: Food -> (Food, Price)
addDrink...
「食べ物+値段」に
addDrinkを適用すると..
> ("beans", Sum 10) `applyLog` addDrink
("milk,Sum {getSum=35})
> ("dogmeat", Sum 5) `applyLog`...
Control.Monad.Writer
•Writer w a 型
•Writer w a 型のMonadインスタンス
•Writer w a 型を扱う便利関数
Thursday, August 22, 13
Writer w a の定義
newtype Writer w a =
Writer{runWriter::(a,w)}
タプルをラップした型
a が主な値の型
wがおまけのモノイド値の型
Writer値コンストラクタは非公開
代わりにwrit...
Writer w a の
Monadインスタンス
instance (Monoid w) => Monad (Writer w) where
return x = Writer (x, mempty)
(Writer (x, v)) >>= f...
memptyはモノイド値に
よって変わる(多相的)
> runWriter (return 3 :: Writer String Int)
(3,"")
> runWriter (return 3 :: Writer (Sum Int) Int...
次回は
Thursday, August 22, 13
Upcoming SlideShare
Loading in...5
×

Haskell超初心者勉強会17

285

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
285
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Haskell超初心者勉強会17

  1. 1. Haskell超初心者勉強会17 第14章 前半 2013/8/22 Thursday, August 22, 13
  2. 2. 14章はモナドの紹介 •文脈の活用方法がわかるのか? •紹介するモナドは mtl パッケージ内に •ghc-pkg list ¦ grep mtl でインストー ルされていることを確認 Thursday, August 22, 13
  3. 3. Writerモナド •もう一つの値がくっついた値 •くっつく値はログのように振る舞う •すべてのログが単一のログ値にまとま ることを保証できる Thursday, August 22, 13
  4. 4. ナイーブに実装してみる isBigGang :: Int -> Bool isBigGang x = x > 9 isBigGang :: Int -> (Bool, String) isBigGang x = (x > 9, "Compared gang size to 9") Thursday, August 22, 13
  5. 5. すでに文字列(文脈)のくっ ついた値を処理するには? applyLog :: (a, String) -> (a -> (b, String)) -> (b, String) applyLog (x, log) f = let (y, newLog) = f x in (y, log ++ newLog) >>= と似た感じ (>>=) :: m a -> (a -> m b) -> m b Thursday, August 22, 13
  6. 6. applyLogを使ってみる •ログが連結される •関数は文脈なしの値を引数にとる > (3, "abc") `applyLog` isBigGang (False, "abcCompared gang size to 9") > ("Tobin", "Got outlaw name.") `applyLog` (x -> (length x, "Applied length.") (5, "Got out lawname. Applied length.") Thursday, August 22, 13
  7. 7. モノイドが助けに来たよ 付加情報はStringにかぎらずリスト一般にできるよね。 ++使ってるし。 applyLog :: (a,[c]) -> (a -> (b,[c])) -> (b,[c]) 付加情報としてByteStringも使いたい。 でも今の型だとリストしか使えない… リストとByteString、両方 Monoid mappend はくっつける操作 Thursday, August 22, 13
  8. 8. モノイドを使って 書き換えてみる applyLog :: (Monoid m) => (a,m)->(a->(b,m))->(b,m) applyLog (x, log) f = let (y, newLog) = f x in (y, log `mappend` newLog) 「値+ログ」から「値+モノイド値」に 拡張された Thursday, August 22, 13
  9. 9. 食べ物を与えると 飲み物+値段が返る関数 import Data.Monoid type Food = String type Price = Sum Int addDrink :: Food -> (Food, Price) addDrink "beans" = ("milk", Sum 25) addDrink "jerky" = ("whiskey", Sum 99) addDrink _ = ("beer", Sum 30) モノイドは値に計算が 定義されているのがいいね Thursday, August 22, 13
  10. 10. 「食べ物+値段」に addDrinkを適用すると.. > ("beans", Sum 10) `applyLog` addDrink ("milk,Sum {getSum=35}) > ("dogmeat", Sum 5) `applyLog` addDrink ("beer",Sum {getSum=35}) > ("dogmeat", Sum 5) `applyLog` addDrink `applyLog` addDrink ("beer",Sum {getSum=65}) おまけの値はログに限らないことがはっきりした Thursday, August 22, 13
  11. 11. Control.Monad.Writer •Writer w a 型 •Writer w a 型のMonadインスタンス •Writer w a 型を扱う便利関数 Thursday, August 22, 13
  12. 12. Writer w a の定義 newtype Writer w a = Writer{runWriter::(a,w)} タプルをラップした型 a が主な値の型 wがおまけのモノイド値の型 Writer値コンストラクタは非公開 代わりにwriter関数が公開 Thursday, August 22, 13
  13. 13. Writer w a の Monadインスタンス instance (Monoid w) => Monad (Writer w) where return x = Writer (x, mempty) (Writer (x, v)) >>= f = let (Writer (y, v')) = f x in Writer (y, v `mappend` v') >>= と自分で定義した applyLog は タプルがラップされている以外は同じ Thursday, August 22, 13
  14. 14. memptyはモノイド値に よって変わる(多相的) > runWriter (return 3 :: Writer String Int) (3,"") > runWriter (return 3 :: Writer (Sum Int) Int) (3,Sum {getSum=0}) > runWriter (return 3 :: Writer (Product Int) Int) (3,Product {getProduct=1}) Thursday, August 22, 13
  15. 15. 次回は Thursday, August 22, 13
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×