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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
import qualified Data.ByteString.Lazy as BL
import qualified Data.Binary.Put as P
import Control.Monad.State
import Control.Monad.Writer
#define USE_TRANSFORMER 3
#if USE_TRANSFORMER == 1
newtype IdentityT m a = IdentityT { runIdT :: m a }
instance (Monad m) => Monad (IdentityT m) where
return a = IdentityT $ return a
ma >>= f = IdentityT $ runIdT ma >>= runIdT . f
ma >> mb = IdentityT $ runIdT ma >> runIdT mb
instance MonadTrans IdentityT where
lift ma = IdentityT ma
type Out = IdentityT P.PutM ()
writeToFile :: String -> Out -> IO ()
writeToFile path out = BL.writeFile path (P.runPut $ runIdT out >> return ())
#elif USE_TRANSFORMER == 2
instance Monoid Integer where
mappend = (+)
mempty = 0
type Out = WriterT Integer P.PutM ()
writeToFile :: String -> Out -> IO ()
writeToFile path out = do
BL.writeFile path $ P.runPut $ runWriterT out >> return ()
#elif USE_TRANSFORMER == 3
type Out = StateT Integer P.PutM ()
writeToFile :: String -> Out -> IO ()
writeToFile path out = BL.writeFile path $ P.runPut $ runStateT out 0 >> return ()
#endif
data Tree = Node [Tree] | Leaf [Int] deriving Show
makeTree :: Tree
makeTree = makeTree' 9
where makeTree' 0 = Leaf [0..100]
makeTree' n = Node [ makeTree' $ n 1
, makeTree' $ n 1
, makeTree' $ n 1
, makeTree' $ n 1 ]
putInt32 n = lift $ P.putWord32le n
putInt8 n = lift $ P.putWord8 n
putTree :: Tree -> Out
putTree (Node childs) = do
putInt8 123
mapM_ putTree childs
putTree (Leaf nums) = do
mapM_ (putInt32 . fromIntegral) nums
main = do
putStrLn "begin"
writeToFile "test-output.bin" $ putTree makeTree
putStrLn "end"
|