Skip to content

Instantly share code, notes, and snippets.

@geekingfrog
Last active February 10, 2017 14:34
Show Gist options
  • Save geekingfrog/7045ba8dc0cdb5cfafec1fdd8bee074b to your computer and use it in GitHub Desktop.
Save geekingfrog/7045ba8dc0cdb5cfafec1fdd8bee074b to your computer and use it in GitHub Desktop.
data MyState s a = MyState (s -> (a, s))
get :: MyState s s
get = MyState (\s -> (s, s))
put :: s -> MyState s ()
put s = MyState (const ((), s))
modify :: (s -> s) -> MyState s ()
modify f = MyState (\s -> ((), f s))
instance Functor (MyState s) where
-- fmap :: (a -> b) -> (MyState s) a -> (MyState s) b
fmap f (MyState fs) =
MyState $
\s ->
let (val, s') = fs s
in (f val, s')
instance Applicative (MyState s) where
-- pure :: a -> (MyState s) a
pure a = MyState (\s -> (a, s))
-- (<*>) :: (MyState s) (a -> b) -> (MyState s) a -> (MyState s) b
(<*>) (MyState fs) (MyState s1) =
MyState $
\s ->
let (f, s') = fs s
(a, s'') = s1 s'
in (f a, s'')
instance Monad (MyState s) where
-- return :: a -> (MyState s) a
return = pure
-- (>>=) :: (MyState s) a -> (a -> (MyState s) b) -> (MyState s) b
(>>=) (MyState s1) fs =
MyState $
\s ->
let (a, s') = s1 s
(MyState fs') = fs a
in fs' s'
import Control.Monad ((>=>))
data MyStateT s m a = MyStateT (s -> m (a, s))
get :: Monad m => MyStateT s m s
get = MyStateT (\s -> return (s, s))
put :: Monad m => s -> MyStateT s m ()
put s = MyStateT (\_ -> return ((), s))
modify :: Monad m => (s -> s) -> MyStateT s m ()
modify f = MyStateT (\s -> return ((), f s))
instance Monad m => Functor (MyStateT s m) where
-- fmap :: (a -> b) -> (MyStateT s m) a -> (MyStateT s m) b
fmap f (MyStateT fs) =
MyStateT $
fs >=> \(a, s') -> return (f a, s')
-- \s -> fs s >>= \(a, s') -> return (f a, s')
instance Monad m => Applicative (MyStateT s m) where
-- pure :: a -> (MyStateT s m) a
pure a = MyStateT (\s -> return (a, s))
-- (<*>) :: (MyStateT s m) (a -> b) -> (MyStateT s m) a -> (MyStateT s m) b
(<*>) (MyStateT fs) (MyStateT s1) =
MyStateT $
\s -> do
(f, s') <- fs s
(a, s'') <- s1 s'
return (f a, s)
instance Monad m => Monad (MyStateT s m) where
-- return :: a -> (MyStateT s m) a
return = pure
-- (>>=) :: (MyStateT s m) a -> (a -> (MyStateT s m) b) -> (MyStateT s m) b
(>>=) (MyStateT s1) fs = MyStateT $
\s -> do -- s1 s >>= \(a, s') -> let fs a
(a, s') <- s1 s
let (MyStateT fs') = fs a
fs' s'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment