-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLog.hs
65 lines (53 loc) · 1.55 KB
/
Log.hs
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
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE FlexibleContexts #-}
module Log
( Log (Log)
, Event (LogStrLn, LogStr, Indent, Unindent)
, showLog, showLog'
) where
import Data.List
import Data.Maybe
import Data.Monoid
import Control.Monad.RWS
indentWidth = 2 :: Int
newtype Log = Log { getLog :: [Event] }
deriving Monoid
data Event =
LogStrLn String
| LogStr String
| Indent
| Unindent
fromLogStr :: Event -> Maybe String
fromLogStr (LogStr s) = Just s
fromLogStr _ = Nothing
showLog :: Log -> [String]
showLog = snd . showLog' 0
-- it sets the number of indents at the beginning, and
-- returns with the number of indents at the end
showLog' :: Int -> Log -> (Int, [String])
showLog' i l = let
actions = map indent . getLog . mergeLogStr $ l
in execRWS (sequence_ actions) () i
where
indent (LogStrLn s) = do
i <- get
tell [replicate (indentWidth * i) ' ' ++ s]
indent Indent = modify (+ 1)
indent Unindent = modify (subtract 1)
-- showLog = map addIndent . getIndent . mergeLogStr where
-- addIndent (i, s) = replicate (2*i) ' ' ++ s
mergeLogStr :: Log -> Log
mergeLogStr = Log . map g . groupBy f . getLog where
f (LogStr _) (LogStr _) = True
f _ _ = False
g es = if fromLogStr (head es) /= Nothing
then LogStrLn $ intercalate "; " $ map (fromJust . fromLogStr) es
else head es
{-
getIndent :: Log -> [(Int, String)]
getIndent = go 0 . getLog where
go _ [] = []
go i (Indent : es) = go (i+1) es
go i (Unindent : es) = go (i-1) es
go i ((LogStrLn str) : es) = (i, str) : go i es
-}