SlideShare ist ein Scribd-Unternehmen logo
1 von 15
Downloaden Sie, um offline zu lesen
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, "Compared gang size to 9")
Thursday, August 22, 13
すでに文字列(文脈)のくっ
ついた値を処理するには?
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
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
モノイドが助けに来たよ
付加情報はStringにかぎらずリスト一般にできるよね。
++使ってるし。
applyLog :: (a,[c]) -> (a -> (b,[c]))
-> (b,[c])
付加情報としてByteStringも使いたい。
でも今の型だとリストしか使えない…
リストとByteString、両方 Monoid
mappend はくっつける操作
Thursday, August 22, 13
モノイドを使って
書き換えてみる
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
食べ物を与えると
飲み物+値段が返る関数
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
「食べ物+値段」に
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
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値コンストラクタは非公開
代わりにwriter関数が公開
Thursday, August 22, 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
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
次回は
Thursday, August 22, 13

Weitere ähnliche Inhalte

Mehr von Takashi Kawachi

例外のlogを快適に
例外のlogを快適に例外のlogを快適に
例外のlogを快適にTakashi Kawachi
 
最小 Hello World! チャレンジ
最小 Hello World! チャレンジ最小 Hello World! チャレンジ
最小 Hello World! チャレンジTakashi Kawachi
 
Elastic beanstalk と Docker と Play
Elastic beanstalk と Docker と PlayElastic beanstalk と Docker と Play
Elastic beanstalk と Docker と PlayTakashi Kawachi
 
やさしいIteratee入門
やさしいIteratee入門やさしいIteratee入門
やさしいIteratee入門Takashi Kawachi
 
Haskell超初心者勉強会20
Haskell超初心者勉強会20Haskell超初心者勉強会20
Haskell超初心者勉強会20Takashi Kawachi
 
Haskell超初心者勉強会14
Haskell超初心者勉強会14Haskell超初心者勉強会14
Haskell超初心者勉強会14Takashi Kawachi
 
Haskell超初心者勉強会11
Haskell超初心者勉強会11Haskell超初心者勉強会11
Haskell超初心者勉強会11Takashi Kawachi
 
Scalaでの例外処理
Scalaでの例外処理Scalaでの例外処理
Scalaでの例外処理Takashi Kawachi
 

Mehr von Takashi Kawachi (12)

例外のlogを快適に
例外のlogを快適に例外のlogを快適に
例外のlogを快適に
 
MacroPyがすごい
MacroPyがすごいMacroPyがすごい
MacroPyがすごい
 
Silhouette intro
Silhouette introSilhouette intro
Silhouette intro
 
最小 Hello World! チャレンジ
最小 Hello World! チャレンジ最小 Hello World! チャレンジ
最小 Hello World! チャレンジ
 
Sbt doctest
Sbt doctestSbt doctest
Sbt doctest
 
Elastic beanstalk と Docker と Play
Elastic beanstalk と Docker と PlayElastic beanstalk と Docker と Play
Elastic beanstalk と Docker と Play
 
やさしいIteratee入門
やさしいIteratee入門やさしいIteratee入門
やさしいIteratee入門
 
Sbt lock1
Sbt lock1Sbt lock1
Sbt lock1
 
Haskell超初心者勉強会20
Haskell超初心者勉強会20Haskell超初心者勉強会20
Haskell超初心者勉強会20
 
Haskell超初心者勉強会14
Haskell超初心者勉強会14Haskell超初心者勉強会14
Haskell超初心者勉強会14
 
Haskell超初心者勉強会11
Haskell超初心者勉強会11Haskell超初心者勉強会11
Haskell超初心者勉強会11
 
Scalaでの例外処理
Scalaでの例外処理Scalaでの例外処理
Scalaでの例外処理
 

Haskell超初心者勉強会17