Monadeja siellä, monadeja täällä... monadeja kaikkialla? TIES341 Funktio ohjelmointi 2 Kevät 2006
Materiaalia Paras verkkomatsku: http://www.nomaware.com/monads/html/
Komentoanalogiasta vielä Monadityypin m a arvo on komento Huom! Komento on eri asia kuin teko m a tyyppisen lausekkeen laskeminen normaalimuotoon ei aiheuta ko. komennon suorittamista m a tyyppinen lauseke on komennon kuvaus Milloin komento suoritetaan? IO tyyppinen komento suoritetaan vain ja ainoastaan, jos se on sidottu Main modulin main funktioon muissa monadeissa muita tapoja
Monadiluettelo Seuraavassa erilaisia monadimalleja Perustuvat komentoanalogiaan Kukin monadi tuo jonkin imperatiivisen ohjelmoinnin aspektin käyttöön silti koodi on täysin puhtaasti funktionaalista Monadit piilottavat putkiston niin, että itse ongelman ratkaisu on selkeä taitavasti käytettynä
Identiteettimonadi Yksinkertaisin mahdollinen monadi itsessään täysin hyödytön Ei tuo mitään imperatiivisia ominaisuuksia käyttöön newtype Identity a = Identity a instance Monad Identity where return = Identity Identity a >>= f = Identity (f a)
Virhemonadit Poikkeustenkäsittely class Error a where nomsg :: a strmsg :: String > a class Monad m => MonadError e m m > e where throwerror :: e > m a catcherror :: m a > (e > m a) > m a
Virhemonadit: Either String instance Error String where nomsg = unspecified error strmsg s = s instance MonadError String (Either String) where throwerror e = Left e catcherror (Left e) f = f e catcherror ma _ = ma
Listamonadit Kuten aiemmin tuli esitettyä, lista on monadi Lista edustaa hyväntahtoista epädeterminismiä
Tilamonadit 1 Tilamonadi tuo mukaan laskennan tilan class Monad m => MonadState s m m > s where get :: m s put :: s > m () gets :: MonadState s m => (s > a) > m a gets f = do st < get return (f st)
Tilamonadit 2 newtype State s a = State (s > (a,s)) instance Monad (State s) where return a = State (\s > (a,s)) State f >>= g = State $ \s > case f s of (a,s) > case g a of State g' > g' s instance MonadState s (State s) where get = State (\s > (s,s)) put s = State (\_ > ((),s)) runstate :: State s a > s > (a, s) runstate (State f) = f
Ai niin: tietueet data Member = Member { name :: String, age :: Int } Tietue on algebrallisen tietotyypin yleistys kaikki se, mitä data määrittelystä on aiemmin sanottu, pätee Tietueen luonti: Member { name = AJK, age = 28 } Hahmonsovitus: case m of Member { age = 28 } >... Päivitys: m { name = KJK } tässä m :: Member huom! luo kopion tietueesta, ei muuta sitä oikeasti Luku: name m name :: Member > String; age :: Member > Int
Tilamonadit 3 Tilamonadin tila on usein tietue Tilan yhden kentän lukemisessa gets funktio on kiva, esim. gets age on komento, joka palauttaa Membertyyppisen tilan age kentän arvon
Jäsenninmonadi (1) Jäsentimet ovat myös monadeita: newtype Parser t a = Parser ([t] > [(a,[t])] instance Monad (Parser t) where return a = Parser (\ts > [(a,ts)]) Parser p >>= f = Parser $ \ts > flip map (p ts) $ \(a,ts') > case f a of Parser g > g ts'
Jäsenninmonadi (2) instance MonadPlus (Parser t) where mzero = Parser (\_ > []) Parser f `mplus` Parser g = Parser $ \ts > f ts ++ g ts Jäsenninmonadi on olennaisesti lista ja tilamonadin yhdistelmä
Ympäristömonadi Ympäristömonadi (reader monad) on kuin tilamonadi, jonka tilaa ei voi muuttaa tilan voi kyllä syrjäyttää rajatulla alueella class Monad m => MonadReader e m m > e where ask :: m e local :: (e > e) > m a > m a
Ympäristömonadi newtype Reader e a = Reader (e > a) instance Monad (Reader e) where return a = Reader (\_ > a) Reader f >>= g = Reader $ \e > case g (f e) of Reader g' > g' e instance MonadReader e (Reader e) where ask = Reader id local f (Reader g) = Reader (\e > g (f e))
Vakiokirjaston monadit Kaikki edellä esitellyt monadit löytyvät kirjastoista Control.Monad.* Text.ParserCombinators.* ym.
Monadien yhdistäminen Käytännön sovelluksissa joutuu yleensä yhdistelemään eri monadipohjia Käsin tehtynä hyvin työlästä Vakiokirjastossa monadimuuntimet esim. ReaderT Monadimuuntimista saa rakennettua helposti monadipinoja type MyMonad a = ReaderT Env (StateT State Identity) a