Monday, 15 August 2011

operator overloading - Define a new monad in Haskell? -



operator overloading - Define a new monad in Haskell? -

i create own monad in haskell, , have haskell treat other built in monad. instance, here code creating monad updates global state variable each time called, along evaluator uses compute number of times quot function called:

-- define monad type type m = state -> (a, state) type state = int -- define homecoming , bind operators monad homecoming x = (a, x) (>>=) :: m -> (a -> m b) -> m b m >>= k = \x -> allow (a,y) = m x in allow (b,z) = k y in (b,z) -- define tick monad, increments state 1 tick :: m () tick x = ((), x+1) info term = con int | div term term -- define evaluator computes number of times 'quot' called side effect eval :: term -> m int eval (con a) = main.return eval (div t u) = eval t main.>>= \a -> eval u main.>>= \b -> (tick main.>>= \()->main.return(quot b)) reply :: term reply = (div (div (con 1972)(con 2))(con 23)) (result, state) = eval reply 0 main = putstrln ((show result) ++ ", " ++ (show state))

as implemented now, return , >>= belong in namespace main, , have distinguish them prelude.return , prelude.>>=. if wanted haskell treat m other type of monad, , overload monad operators in prelude, how go that?

to create new monad work existing haskell machinery--do notation, instance--all need declare type instance of monad typeclass. prelude functions >>=, return, etc. work new type other monad types.

there's limitation, though, require changes in examples. type synonyms (declared type) cannot made class instances. (your m a exactly same as int -> (a, int).) you'll need utilize data or newtype instead. (the distinction between 2 not relevant here.)

both of keywords create genuinely new type; in particular, create new data constructor. should read on in fundamental haskell text. briefly, newtype x = y (...) creates new type x a; can create values of type using constructor y (which can, , does, have same name type constructor x); , can consume values pattern matching on y. if take not export info constructor y, functions in module able manipulate values directly.

(there's ghc extension typesynonyminstances won't help here, because of separate issue: type synonyms cannot partially applied; type x = {- ... -} can write x a or x int or whatnot, never x. can't write instance monad m because m partially applied.)

after that, need move definitions of return , >>= instance monad declaration:

newtype m = m (state -> (a, state)) instance monad m homecoming = m $ \x -> (a, x) m >>= k = {- ... -}

note implementation of (>>=) verbose because need disclose , rewrap newtype using info constructor m. @ the implementation of statet in transformers, uses record accessor create easier. (you can manually write function runm :: m -> state -> (a, state) equivalent record syntax transformers , many other packages use.)

haskell operator-overloading monads

No comments:

Post a Comment