Advertisement
Guest User

ExceptT Control.Foldl example

a guest
Oct 2nd, 2015
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import           Pipes
  2. import qualified Pipes.Prelude as P
  3. import qualified Control.Foldl as L
  4. import           Control.Monad.Except
  5.  
  6. type ErrorReturnType = Either String ()
  7.  
  8. exampleProd :: Monad m => Producer (Int, Int) m ErrorReturnType
  9. exampleProd = fmap Right $ each $ zip [1,1,1,1,2,2,2,2,4,4,4,4] [1,2,3,4,1,2,3,4,1,2,4,3]
  10.  
  11. printEveryElement :: MonadIO m => L.FoldM m (Int, Int) ()
  12. printEveryElement = L.FoldM (\x a -> liftIO $ print a) (return ()) return
  13.  
  14. -- check that the inner loop consists of 1,2,3,4
  15. checkInnerLoop :: Monad m => L.FoldM (ExceptT String m) (Int, Int) ()
  16. checkInnerLoop = L.FoldM step init done
  17.   where
  18.     init :: Monad m => (ExceptT String m) Int
  19.     init = return 1
  20.     step :: Monad m => Int -> (Int, Int) -> ExceptT String m Int
  21.     step state (_, inner) =
  22.         if state == inner then
  23.             return $ (state `mod` 4) + 1
  24.         else
  25.             throwError "Error in inner counter"
  26.     done :: Monad m => Int -> ExceptT String m ()
  27.     done = \_ -> return ()
  28.  
  29. -- check that the outer loop increases every four entries
  30. checkOuterLoop :: Monad m => L.FoldM (ExceptT String m) (Int, Int) ()
  31. checkOuterLoop = L.FoldM step init done
  32.   where
  33.     init :: Monad m => (ExceptT String m) Int
  34.     init = return 0
  35.     step :: Monad m => Int -> (Int, Int) -> ExceptT String m Int
  36.     step state (outer, _) =
  37.         if ((state `div` 4) + 1) == outer then
  38.             return $ state + 1
  39.         else
  40.             throwError "Error in outer counter"
  41.     done :: Monad m => Int -> ExceptT String m ()
  42.     done = \_ -> return ()
  43.  
  44. -- just check the inner loop
  45. combinedFold :: MonadIO m => L.FoldM (ExceptT String m) (Int, Int) ((),())
  46. combinedFold = (,) <$> printEveryElement <*> checkInnerLoop
  47.  
  48. -- just check the outer loop
  49. combinedFold2 :: MonadIO m => L.FoldM (ExceptT String m) (Int, Int) ((),(),())
  50. combinedFold2 = (,,) <$> printEveryElement <*> checkInnerLoop <*> checkOuterLoop
  51.  
  52. main :: IO ()
  53. main = do
  54.     r <- runExceptT $ L.impurely P.foldM' combinedFold exampleProd
  55.    print r
  56.    r <- runExceptT $ L.impurely P.foldM' combinedFold2 exampleProd
  57.     print r
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement