/
2013-12-14-acid-state.hs
53 lines (42 loc) · 1.41 KB
/
2013-12-14-acid-state.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
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
import Control.Applicative
import Control.Monad.Reader (ask)
import Control.Monad.State (modify)
import Data.Acid
import Data.Function
import Data.IntMap (IntMap)
import Data.List
import Data.Ord
import Data.SafeCopy
import Data.Typeable
import Data.Time
import qualified Data.IntMap as IntMap
data Failure = Failure { failureReason :: String
, failureTime :: UTCTime
} deriving (Show, Typeable)
data FailureDb = FailureDb { allFailures :: IntMap Failure }
deriving (Typeable)
failuresOverTime :: Query FailureDb [Failure]
failuresOverTime =
sortBy (comparing failureTime) . IntMap.elems . allFailures <$> ask
addFailure :: Failure -> Update FailureDb ()
addFailure failure = modify go
where
go (FailureDb db) = FailureDb $
case IntMap.maxViewWithKey db of
Just ((max, _), _) -> IntMap.insert (max + 1) failure db
Nothing -> IntMap.singleton 1 failure
deriveSafeCopy 0 'base ''Failure
deriveSafeCopy 0 'base ''FailureDb
makeAcidic ''FailureDb ['failuresOverTime, 'addFailure]
main :: IO ()
main = do
state <- openLocalState (FailureDb IntMap.empty)
-- Record a new failure
now <- getCurrentTime
update state (AddFailure $ Failure "ENOMISSLES" now)
-- Query for all failures
allFailures <- query state FailuresOverTime
mapM_ print allFailures