Advertisement
gatoatigrado

Control.RMonad.Trans.State

Sep 7th, 2011
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.86 KB | None | 0 0
  1. {-# LANGUAGE CPP,
  2. MultiParamTypeClasses,
  3. NoImplicitPrelude,
  4. FlexibleContexts,
  5. FlexibleInstances,
  6. RebindableSyntax,
  7. TypeFamilies,
  8. UndecidableInstances #-}
  9.  
  10. module Control.RMonad.Trans.State where
  11.  
  12. import Control.RMonad.Prelude
  13. import Control.RMonad
  14.  
  15. import Data.Suitable
  16.  
  17. -- anything suitable in the parent should be suitable here
  18. newtype StateT s 𝔪 α = StateT { runStateT :: s -> 𝔪 (α, s) }
  19.  
  20. #define TYP_CONSTR (Suitable 𝔪 α, Suitable 𝔪 (α, s))
  21. data instance Constraints (StateT s 𝔪) α =
  22. TYP_CONSTR => StateT_Constraints
  23. instance TYP_CONSTR => Suitable (StateT s 𝔪) α where
  24. constraints = StateT_Constraints
  25.  
  26. instance RMonad 𝔪 => RMonad (StateT s 𝔪) where
  27. return x = withResConstraints $ \StateT_Constraints ->
  28. (StateT $ \s -> return (x, s))
  29. m >>= k = withConstraintsOf m $ \StateT_Constraints ->
  30. withResConstraints $ \StateT_Constraints ->
  31. StateT $ \s -> do
  32. ~(a, s') <- runStateT m s
  33. runStateT (k a) s'
  34.  
  35. -- |Similar to 'evalState'
  36. evalStateT
  37. :: (Suitable m (b, s), Suitable m b, RMonad m) =>
  38. StateT s m b -> s -> m b
  39. evalStateT m s = do
  40. ~(a, _) <- runStateT m s
  41. return a
  42.  
  43. -- |Similar to 'execState'
  44. execStateT
  45. :: (Suitable m (α, b), Suitable m b, RMonad m) =>
  46. StateT b m α -> b -> m b
  47. execStateT m s = do
  48. ~(_, s') <- runStateT m s
  49. return s'
  50.  
  51. -- |Similar to 'mapState'
  52. mapStateT
  53. :: (𝔪1 (α1, s) -> 𝔪 (α, s)) -> StateT s 𝔪1 α1 -> StateT s 𝔪 α
  54. mapStateT f m = StateT $ f . runStateT m
  55.  
  56. -- |Similar to 'withState'
  57. withStateT :: (s -> s) -> StateT s 𝔪 α -> StateT s 𝔪 α
  58. withStateT f m = StateT $ runStateT m . f
  59.  
  60. instance (RFunctor m) => RFunctor (StateT s m) where
  61. fmap f m = withConstraintsOf m $ \StateT_Constraints ->
  62. withResConstraints $ \StateT_Constraints ->
  63. StateT $ \ s ->
  64. fmap (\ ~(a, s') -> (f a, s')) $ runStateT m s
  65.  
  66. -- NOTE: type inference will not infer this header
  67. get :: (RMonad 𝔪, Suitable 𝔪 (s, s)) => StateT s 𝔪 s
  68. get = StateT $ \s -> return (s, s)
  69.  
  70. -- | More useful than put, returns previous value
  71. set :: (RMonad 𝔪, Suitable 𝔪 (s, s)) => s -> StateT s 𝔪 s
  72. set s = StateT $ \s_old -> return (s_old, s)
  73.  
  74. -- | Monadic state transformer.
  75. -- Maps an old state to a new state inside a state monad.
  76. -- The old state is returned
  77. modify :: (RMonad 𝔪, Suitable 𝔪 s, Suitable 𝔪 (s, s)) =>
  78. (s -> s) -> StateT s 𝔪 s
  79. modify f = get >>= set . f
  80.  
  81. -- | Gets specific component of the state, using a projection function
  82. -- supplied.
  83. gets
  84. :: (RMonad 𝔪,
  85. Suitable 𝔪 (a, a),
  86. Suitable 𝔪 (b, a),
  87. Suitable 𝔪 b,
  88. Suitable 𝔪 a) =>
  89. (a -> b) -> StateT a 𝔪 b
  90. gets f = get >>= return . f
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement