fradrive/src/Handler/Utils/Corrections.hs
2022-10-12 09:35:16 +02:00

52 lines
2.0 KiB
Haskell

-- SPDX-FileCopyrightText: 2022 Sarah Vaupel <vaupel.sarah@campus.lmu.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
module Handler.Utils.Corrections where
import Import
-- CorrectionInfo has seeming redundancies, but these are useful for aggregation
-- INVARIANT: isJust ciTot `implies` ciCorrected > 0
data CorrectionInfo = CorrectionInfo
{ ciSubmittors, ciSubmissions, ciAssigned, ciCorrected :: Integer
, ciCorrector :: Maybe UserId
, ciTot, ciMin, ciMax :: Maybe NominalDiffTime
}
instance Semigroup CorrectionInfo where
corrA <> corrB =
assert (isJust (ciTot corrA) `implies` (ciCorrected corrA > 0)) $
assert (isJust (ciTot corrB) `implies` (ciCorrected corrB > 0))
CorrectionInfo
{ ciSubmittors = ciSubmittors `mergeWith` (+)
, ciSubmissions = ciSubmissions `mergeWith` (+)
, ciAssigned = ciAssigned `mergeWith` (+)
, ciCorrected = ciCorrected `mergeWith` (+)
, ciCorrector = ciCorrector `mergeWith` keepEqual
, ciTot = ciTot `mergeWith` ignoreNothing (+)
, ciMin = ciMin `mergeWith` ignoreNothing min
, ciMax = ciMax `mergeWith` ignoreNothing max
}
where
mergeWith :: (CorrectionInfo -> a) -> (a -> a -> c) -> c
mergeWith prj f = on f prj corrA corrB
keepEqual (Just x) (Just y) | x==y = Just x
keepEqual Nothing other = other
keepEqual other Nothing = other
keepEqual _ _ = Nothing
instance Monoid CorrectionInfo where
mappend = (<>)
mempty = CorrectionInfo { ciSubmittors = 0
, ciSubmissions = 0
, ciAssigned = 0
, ciCorrected = 0
, ciCorrector = Nothing
, ciMin = Nothing
, ciTot = Nothing
, ciMax = Nothing
}