Advertisement
Guest User

Untitled

a guest
Aug 17th, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.22 KB | None | 0 0
  1. {-# LANGUAGE FlexibleInstances #-}
  2. {-# LANGUAGE InstanceSigs #-}
  3. {-# LANGUAGE MultiParamTypeClasses #-}
  4. {-# LANGUAGE ScopedTypeVariables #-}
  5. {-# LANGUAGE UndecidableInstances #-}
  6.  
  7. module Loop where
  8.  
  9. import Prelude hiding (break)
  10.  
  11. import Control.Monad (ap)
  12. import Control.Monad.State.Lazy (MonadState(..))
  13. import Control.Monad.Trans (MonadTrans(..))
  14.  
  15. data Loop a r = Break a
  16. | Continue a
  17. | Value r
  18.  
  19. instance Functor (Loop a) where
  20. fmap :: (r -> s) -> Loop a r -> Loop a s
  21. fmap _ (Break t) = Break t
  22. fmap _ (Continue t) = Continue t
  23. fmap f (Value x) = Value (f x)
  24.  
  25. newtype LoopT a m r = LoopT { runLoopT :: m (Loop a r) }
  26.  
  27. instance Functor m => Functor (LoopT a m) where
  28. fmap :: (r -> s) -> LoopT a m r -> LoopT a m s
  29. fmap f (LoopT mx) = LoopT (fmap (fmap f) mx)
  30.  
  31. instance Monad m => Applicative (LoopT a m) where
  32. pure :: r -> LoopT a m r
  33. pure = LoopT . pure . Value
  34.  
  35. (<*>) :: LoopT a m (r -> s) -> LoopT a m r -> LoopT a m s
  36. (<*>) = ap
  37.  
  38. instance Monad m => Monad (LoopT a m) where
  39. (>>=) :: LoopT a m r -> (r -> LoopT a m s) -> LoopT a m s
  40. (LoopT mx) >>= f = LoopT $ do x <- mx
  41. case x of
  42. Break t -> return (Break t)
  43. Continue t -> return (Continue t)
  44. Value y -> runLoopT (f y)
  45.  
  46. instance MonadTrans (LoopT a) where
  47. lift :: Monad m => m r -> LoopT t m r
  48. lift = LoopT . fmap Value
  49.  
  50. instance MonadState s m => MonadState s (LoopT a m) where
  51. get :: LoopT a m s
  52. get = lift get
  53.  
  54. put :: s -> LoopT a m ()
  55. put = lift . put
  56.  
  57. break :: Monad m => a -> LoopT a m ΠΊ
  58. break = LoopT . return . Break
  59.  
  60. continue :: Monad m => a -> LoopT a m r
  61. continue = LoopT . return . Continue
  62.  
  63. inCycle :: Functor m => LoopT a m a -> LoopT a m a
  64. inCycle (LoopT mx) = LoopT (fmap go mx)
  65. where
  66. go :: Loop a a -> Loop a a
  67. go (Break x) = Break x
  68. go (Continue x) = Value x
  69. go (Value x) = Value x
  70.  
  71. afterCycle :: Functor m => LoopT a m a -> m a
  72. afterCycle (LoopT mx) = fmap go mx
  73. where
  74. go :: Loop a a -> a
  75. go (Break x) = x
  76. go (Continue x) = x
  77. go (Value x) = x
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement