{-# LANGUAGE DeriveGeneric #-} module Validator ( validate, Invalid(..) ) where import Ast import Control.Monad ( forM_ ) import Text.PrettyPrint.GenericPretty data Invalid = PointsExceedMaxPoints Header | BadSubJudgementPointsSum Judgement | BadSubJudgementMaxPointsSum Judgement deriving (Eq, Show, Generic) instance Out Invalid try :: Bool -> Invalid -> Either Invalid () try True = \_ -> Right () try False = Left infix 4 ~= (~=) :: Double -> Double -> Bool x ~= y = abs (x - y) <= 0.01 validate :: Judgement -> Either Invalid () validate j @ (Judgement (h @ (Header (_, p, maxP)), _, subjs)) = do try (p <= maxP) (PointsExceedMaxPoints h) try ((sum $ map points subjs) ~= p) (BadSubJudgementPointsSum j) try ((sum $ map maxPoints subjs) ~= maxP) (BadSubJudgementMaxPointsSum j) forM_ subjs validate points :: Judgement -> Double points (Judgement (Header (_, v, _), _, _)) = v maxPoints :: Judgement -> Double maxPoints (Judgement (Header (_, _, v), _, _)) = v