Add general functions to UE2

This commit is contained in:
Ivaylo Ivanov 2021-10-24 13:25:20 +02:00
parent 5b09fc7b2e
commit 512026a34c

View File

@ -30,7 +30,11 @@ data Tag = I | II | III | IV | V | VI | VII | VIII | IX | X
data Monat = Jan | Feb | Mar | Apr | Mai | Jun
| Jul | Aug | Sep | Okt | Nov | Dez deriving (Eq,Ord,Show)
type Jahr = Nat1
data Datum = D Tag Monat Jahr deriving (Eq,Show,Ord)
data Datum = D {
tag :: Tag,
monat :: Monat,
jahr :: Jahr
} deriving (Eq,Show,Ord)
data Testart = PCR | Antigen deriving (Eq,Show,Ord)
data Impfstoff = AstraZeneca | BioNTec | JundJ | Moderna
| Sputnik | Sinovac deriving (Eq,Show,Ord)
@ -60,6 +64,41 @@ type Abzuweisende = [VorUndNachname]
type Kontrollzeitpunkt = (Datum,Uhrzeit)
data Kontrollergebnis = Einlassen | Abweisen | Ungueltig deriving (Eq,Show)
-- General functions
was_sick :: Person -> Bool
was_sick p
| dreig_status p == Genesen = True
| otherwise = False
is_vaccinated :: Person -> Bool
is_vaccinated p =
case dreig_status p of
Geimpft _ _ -> True
_ -> False
is_tested :: Person -> Bool
is_tested p =
case dreig_status p of
Getestet _ _ _ -> True
_ -> False
full_months::[Monat]
full_months = [Jan, Mar, Mai, Jul, Aug, Okt, Dez]
is_date_valid :: (Datum, Uhrzeit) -> Bool
is_date_valid (d, u)
| monat d == Feb =
let y = jahr d in
let t = tag d in
if y `mod` 4 /= 0 && t > XXVIII then False
else
if y `mod` 100 == 0 && y `mod` 400 /= 0 then False
else
if t > XXIX then False
else True
| tag d > XXX && not(monat d `elem` full_months) = False
| tag d > XXXI = False
| otherwise = True
-- Aufgabe A.2
{- Knapp, aber gut nachvollziehbar geht einzulassen folgendermassen vor:
@ -69,9 +108,25 @@ data Kontrollergebnis = Einlassen | Abweisen | Ungueltig deriving (Eq,Show)
einzulassen :: (Person,Regel,Kontrollzeitpunkt) -> Kontrollergebnis
einzulassen (p, r, k)
| dreig_status p == Udrei = Abweisen
| r == ZweiG =
| otherwise = should_allow p r k
should_allow :: Person -> Regel -> Kontrollzeitpunkt -> Kontrollergebnis
should_allow p ZweiG k
| (not (was_sick p)) || (not (is_vaccinated p)) = Abweisen
| otherwise = check_cert_validity p k
should_allow p ZweieinhalbG k
| is_tested p =
if testart (dreig_status p) == Antigen then Abweisen
else Einlassen
else check_cert_validity p k
| otherwise = check_cert_validity p k
should_allow p DreiG k = check_cert_validity p k
check_cert_validity :: Person -> Kontrollzeitpunkt -> Kontrollergebnis
check_cert_validity p k
| not(is_date_valid k) = Ungueltig
| is_tested p && not(is_date_valid ((datum (dreig_status p)), (uhrzeit (dreig_status p)))) = Ungueltig
| otherwise = Einlassen
-- Aufgabe A.3
@ -110,9 +165,3 @@ einzulassen (p, r, k)
folgendermassen vor:
...
-}