Minor improvement in WorkIndex type to eliminate duplicated information.
[?]
Mar 9, 2014, 4:41 AM
Y35QCWYW2OTZ27ZVTH2BA3XJTUCJ2WMLKU32ZCOCDY3AW7TIZXRACDependencies
- [2]
2KZPOGRBOnce you get Haskell to compile, the tests pass! - [3]
4QX5E5ACInitial compilation of payouts function succeeds. - [4]
7DBNV3GVInitial, stack-based impl of time log event reduction. - [5]
JUUMYIQEAdd groupBy utility function for use in TimeLog. - [6]
EQXRXRZDChanged to use tasty instead of test-framework - [7]
N4NDAZYTInitial implementation of payouts. - [8]
NVOCQVASInitial failing tests. - [9]
ADMKQQGCInitial empty Snap project.
Change contents
- replacement in ananke.cabal at line 32
containers == 0.5.*,postgresql-simple >= 0.3.10containers == 0.5.* - edit in ananke.cabal at line 44
bifunctors, - replacement in src/Ananke/TimeLog.hs at line 6
, LogEvent(..), WorkEvent(..), WorkIndex - replacement in src/Ananke/TimeLog.hs at line 20
import Database.PostgreSQL.Simple.FromRowimport Database.PostgreSQL.Simple.FromField-- import Database.PostgreSQL.Simple.FromRow-- import Database.PostgreSQL.Simple.FromField - replacement in src/Ananke/TimeLog.hs at line 25
data LogEvent = StartWork | StopWork deriving (Show, Eq)data WorkEvent = StartWork { logTime :: UTCTime }| StopWork { logTime :: UTCTime } deriving (Show, Eq) - replacement in src/Ananke/TimeLog.hs at line 31
instance FromField LogEvent wherefromField f m = let fromText "start_work" = return StartWorkfromText "stop_work" = return StopWorkfromText a = conversionError $ LogEventParseError $ "unrecognized log event type " ++ ain fromField f m >>= fromText-- instance FromField WorkEvent where-- fromField f m = let fromText "start_work" = return StartWork-- fromText "stop_work" = return StopWork-- fromText a = conversionError $ LogEventParseError $ "unrecognized log event type " ++ a-- in fromField f m >>= fromText - replacement in src/Ananke/TimeLog.hs at line 38
, logTime :: UTCTime, event :: LogEvent, event :: WorkEvent - replacement in src/Ananke/TimeLog.hs at line 41
instance FromRow LogEntry wherefromRow = LogEntry <$> field <*> field <*> field-- instance FromRow LogEntry where-- fromRow = LogEntry <$> field <*> field <*> field - replacement in src/Ananke/TimeLog.hs at line 48
type WorkIndex = Map BtcAddr ([LogEntry], [LogInterval])type WorkIndex = Map BtcAddr ([WorkEvent], [Interval]) - replacement in src/Ananke/TimeLog.hs at line 65
payouts dep ptime widx = let addIntervalDiff :: (Functor f, Foldable f) => NDT -> f LogInterval -> (NDT, NDT)addIntervalDiff total ivals = (\dt -> (dt + total, dt)) $ sumLogIntervals dep ptime ivals(totalTime, keyTimes) = M.mapAccum addIntervalDiff (fromInteger 0) $ M.map snd widxin M.map (\kt -> toRational $ kt / totalTime) keyTimespayouts dep ptime widx =let addIntervalDiff :: (Functor f, Foldable f) => NDT -> f Interval -> (NDT, NDT)addIntervalDiff total ivals = (\dt -> (dt + total, dt)) $ workCredit dep ptime ivals(totalTime, keyTimes) = M.mapAccum addIntervalDiff (fromInteger 0) $ M.map snd widxin M.map (\kt -> toRational $ kt / totalTime) keyTimes - replacement in src/Ananke/TimeLog.hs at line 72
Given a depreciation function, the "current" time, and a foldable functor of log intervals,produce the total, depreciated length of work to be credited to an address. - replacement in src/Ananke/TimeLog.hs at line 75
sumLogIntervals :: (Functor f, Foldable f) => Depreciation -> UTCTime -> f LogInterval -> NDTsumLogIntervals dep ptime ivals = F.foldl' (+) (fromInteger 0) $ fmap (depreciateInterval dep ptime) ivalsworkCredit :: (Functor f, Foldable f) => Depreciation -> UTCTime -> f Interval -> NDTworkCredit dep ptime ivals = F.foldl' (+) (fromInteger 0) $ fmap (depreciateInterval dep ptime) ivals - replacement in src/Ananke/TimeLog.hs at line 78
depreciateInterval :: Depreciation -> UTCTime -> LogInterval -> NDTdepreciateInterval dep ptime ival = let depreciation :: Rationaldepreciation = depf dep $ diffUTCTime ptime (end . workInterval $ ival)in fromRational $ depreciation * (toRational . ilen . workInterval $ ival){-|Compute the depreciated difftime for a single Interval value.-}depreciateInterval :: Depreciation -> UTCTime -> Interval -> NDTdepreciateInterval dep ptime ival =let depreciation :: Rationaldepreciation = depf dep $ diffUTCTime ptime (end $ ival)in fromRational $ depreciation * (toRational . ilen $ ival) - replacement in src/Ananke/TimeLog.hs at line 88
intervals = F.foldl' appendLogEntry M.emptyintervals logEntries = M.map (bimap (fmap event) (fmap workInterval)) $ F.foldl' appendLogEntry M.empty logEntries - replacement in src/Ananke/TimeLog.hs at line 90
appendLogEntry :: WorkIndex -> LogEntry -> WorkIndexappendLogEntry workIndex entry = let acc = reduceToIntervals $ pushEntry entry workIndexin insert (btcAddr entry) acc workIndextype RawIndex = Map BtcAddr ([LogEntry], [LogInterval]) - replacement in src/Ananke/TimeLog.hs at line 92
pushEntry :: LogEntry -> WorkIndex -> ([LogEntry], [LogInterval])appendLogEntry :: RawIndex -> LogEntry -> RawIndexappendLogEntry workIndex entry =let acc = reduceToIntervals $ pushEntry entry workIndexin insert (btcAddr entry) acc workIndexpushEntry :: LogEntry -> RawIndex -> ([LogEntry], [LogInterval]) - replacement in src/Ananke/TimeLog.hs at line 101
reduceToIntervals ((LogEntry addr end StopWork) : (LogEntry _ start StartWork) : xs, intervals) = (xs, (LogInterval addr (interval start end)) : intervals)reduceToIntervals ((LogEntry addr (StopWork end)) : (LogEntry _ (StartWork start)) : xs, intervals) =(xs, (LogInterval addr (interval start end)) : intervals) - replacement in src/Ananke.hs at line 7
import Database.PostgreSQL.Simple.FromField--import Database.PostgreSQL.Simple.FromField - replacement in src/Ananke.hs at line 14
instance FromField BtcAddr wherefromField f m = fmap BtcAddr $ fromField f m--instance FromField BtcAddr where-- fromField f m = fmap BtcAddr $ fromField f m - edit in test/Test.hs at line 1
{-# LANGUAGE ScopedTypeVariables #-} - edit in test/Test.hs at line 6
import Data.Bifunctor as B - edit in test/Test.hs at line 37
testLogEntries :: [LogEntry] - replacement in test/Test.hs at line 42
[ LogEntry addr start StartWork, LogEntry addr end StopWork ][ LogEntry addr (StartWork start), LogEntry addr (StopWork end) ] - edit in test/Test.hs at line 44
testIntervals :: [LogInterval] - edit in test/Test.hs at line 49
expected0 :: Map BtcAddr ([LogEntry], [LogInterval])expected0 = M.map (const [] &&& id) . fromListWith (++) . fmap (intervalBtcAddr &&& return) $ testIntervals - replacement in test/Test.hs at line 53
expected = M.map (\i -> ([], i)) . fromListWith (++) . fmap (intervalBtcAddr &&& return) $ testIntervalsexpected :: WorkIndexexpected = M.map (bimap (fmap event) (fmap workInterval)) expected0