Conduit with StateT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
module Main where

import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Data.Conduit
import Control.Monad.State
import qualified Data.Conduit.List as CL

{- |

  This shows how to transfer a

  >c1 :: Conduit Int (StateT Int m) String

  into a

  >c2 :: Conduit Int m String
-}

conduitWithState :: (MonadIO m) => Conduit Int (StateT Int m) String
conduitWithState = do
  liftIO $ putStrLn $ "Counting Int->String converter ready!"
  awaitForever $ \x -> do
    i <- lift get
    lift $ modify (+1)
    liftIO $ putStrLn $ "Converting " ++ show x ++ " to a string! " ++
                        "Processed so far: " ++ show i
    yield (show x)


countingConverterConduit :: (MonadIO m) => Conduit Int m String
countingConverterConduit = transPipe (\stateTint -> evalStateT stateTint 1)  conduitWithState


main :: IO ()
main = do
  stringList <- CL.sourceList [4,1,9,7,3] $=
     countingConverterConduit $$
     CL.consume
  print stringList

-- PROBLEM:
-- Prints "Processed so far: 1" only instead of counting up!
22:12: Warning: Redundant $
Found:
putStrLn $ "Counting Int->String converter ready!"
Why not:
putStrLn "Counting Int->String converter ready!"
32:39: Warning: Avoid lambda
Found:
\ stateTint -> evalStateT stateTint 1
Why not:
(`evalStateT` 1)

Conduit with StateT (annotation)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
module Main where

import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Data.Conduit
import Control.Monad.State
import qualified Data.Conduit.List as CL

{- |

  This shows how to transfer a

  >c1 :: Conduit Int (StateT Int m) String

  into a

  >c2 :: Conduit Int m String
-}

conduitWithState :: (MonadIO m) => Conduit Int (StateT Int m) String
conduitWithState = do
  liftIO $ putStrLn $ "Counting Int->String converter ready!"
  awaitForever $ \x -> do
    i <- lift get
    lift $ modify (+1)
    liftIO $ putStrLn $ "Converting " ++ show x ++ " to a string! " ++
                        "Processed so far: " ++ show i
    yield (show x)


main :: IO ()
main = do
  stringList <- flip evalStateT 1 $
     -- This pipeline will produce a StateT Int IO [String]
     -- so from there you can evalStateT
     -- to end up with an IO [String]
     CL.sourceList [4,1,9,7,3] $=
     conduitWithState  $$
     CL.consume
  print stringList
22:12: Warning: Redundant $
Found:
putStrLn $ "Counting Int->String converter ready!"
Why not:
putStrLn "Counting Int->String converter ready!"