Safe HaskellSafe

BRP

Description

První domácí úloha do Semináře z funkcionálního programování IB016, semestr jaro 2019.

Zadání

Vaším úkolem bude vytvořit jednoduchou implementaci zjednodušeného systému residentního parkování v Brně.

Systém si uchovává informace o residentech, kteří pak mohou parkovat své jediné auto v libovolné brněnské zóně.

Parkovat v Brně však mohou i návštěvníci, avšak musí za každou minutu, již zde stáli, zaplatit jeden peníz.

Systém má uloženu databasi zón, kde je známo, zda v dané zóně mohou parkovat pouze residenti, nebo i návštěvníci.

Backend

Definujte datové typy Zones, Parked, ZoneType, které odpovídají vnitřní struktuře vašich databasí. Pomněte, že se nemusí (ale může) jednat o typové aliasy.

Implementujte všechny funkce v zadání implementované jako undefined krom funkce interactive. Držte se přesně dokumentace k těmto funkcím.

Interaktivní klient

Implementujte interaktivní klient čtoucí standardní vstup a píšící na standardní výstup. Všechny po něm požadované funkce najdete v jeho dokumentaci (funkce interactive).

Bonus

Brněnští strážníci mají vyfoceno auto, kterak pádí po brněnských ulicích nepovolenou rychlostí. Kvůli této však není poznávací značka jasně čitelná. Pomozte mužům zákona identifikovat pachatele (pokud je registrovaným Brňanem).

Přidejte do interaktivního klientu funkci, jíž bude zadána poznávací značka, kde některé znaky (krom mezery na čtvrté posici) budou nahrazeny znakem '_'. Nalezněte všechna vozidla, která se nachází v databasi, jejichž poznávací značky mohou nahrazením některých znaků znakem '_' splynout se vstupem. Navíc vrácená vozidla opatřete informací o majiteli, je-li tento v databasi residentů, a zóně, je-li vozidlo v některé právě zaparkováno.

Bodování

Rozdělení bodů do částí je následující:

  • Za backend část můžete získat 7 bodů.
  • Za interaktivní část můžete získat 3 body.
  • Za bonus můžete získat další 1 bod (a k tomu spoustu zábavy s Haskellem).
  • Za peer review můžete získat až 3 body.

Povolené knihovny

Můžete použít libovolný modul z balíčku base a containers

Dále, pro hezčí zdrojový kód, je povoleno užívat balíček unicode-prelude

Užití žádných jiných balíků dovoleno není.

Mějte na paměti, že psaní vlastních funkcí, které je lze nalézt v povolených modulech, BUDE penalisováno. Proto doporučujeme pečlivě prostudovat především moduly Data.Set a Data.Map. Rozhodně neprohloupíte, když si navíc prohlédnete i Prelude, Data.List a Data.Maybe

Synopsis

Documentation

data Car #

Datová struktura pro ukládání vozů

Instances
Eq Car # 
Instance details

Defined in BRP

Methods

(==) :: Car -> Car -> Bool

(/=) :: Car -> Car -> Bool

Ord Car # 
Instance details

Defined in BRP

Methods

compare :: Car -> Car -> Ordering

(<) :: Car -> Car -> Bool

(<=) :: Car -> Car -> Bool

(>) :: Car -> Car -> Bool

(>=) :: Car -> Car -> Bool

max :: Car -> Car -> Car

min :: Car -> Car -> Car

Show Car # 
Instance details

Defined in BRP

Methods

showsPrec :: Int -> Car -> ShowS

show :: Car -> String

showList :: [Car] -> ShowS

data Person #

Datová struktura pro ukládání osob.

Dvě osoby jsou stejné právě tehdy, když mají stejná čísla občanských průkazů.

Instances
Eq Person # 
Instance details

Defined in BRP

Methods

(==) :: Person -> Person -> Bool

(/=) :: Person -> Person -> Bool

Ord Person # 
Instance details

Defined in BRP

Methods

compare :: Person -> Person -> Ordering

(<) :: Person -> Person -> Bool

(<=) :: Person -> Person -> Bool

(>) :: Person -> Person -> Bool

(>=) :: Person -> Person -> Bool

max :: Person -> Person -> Person

min :: Person -> Person -> Person

Show Person # 
Instance details

Defined in BRP

Methods

showsPrec :: Int -> Person -> ShowS

show :: Person -> String

showList :: [Person] -> ShowS

type Database = (Residents, Zones, Parked) #

Typový alias vyjadřující typ všech informací, které má úřad v kterékoli chvíli k disposici.

createCar #

Arguments

:: String

poznávací značka

-> Maybe Car 

Vrátí hodnotu automobilového typu za předpokladu, že má řetězec tvar poznávací značky.

Tvar poznávací značky je následující:

{Čís}{VP}{Čís|VP}{mezera}{Čís}{Čís}{Čís}{Čís} kde {Čís} je libovolná číslice a {VP} je libovolné velké písmeno anglické abecedy, kromě G, O, Q, W.

Pokud nemá řetězec požadovaný tvar, vrátí Nothing, jinak vrátí řetězec zabalený do konstruktorů Just Car

V celém zbytku řešení je zakázáno používat konstruktor Car k vytváření hodnot typu Car (tedy je povoleno jej používat právě k pattern matchingu).

addResident #

Arguments

:: Residents

residenti

-> Person

osoba k přidání

-> Maybe Car

samohyb patřící osobě

-> Residents 

Přidá nového residenta.

Pokud již daná osoba je uložena, nebo daný vůz napsaný na některou osobu, vrátí funkce hodnotu nezměněného prvního argumentu.

Pokud je jako samohyb předána hodnota Nothing je přidána osoba bez přiřazeného samohybu.

updateCar #

Arguments

:: Residents

residenti

-> Person

osoba s novým samohybem

-> Maybe Car

nový samohyb

-> Residents 

Změní vůz napsaný na danou osobu, případně přiřadí vůz nový, pokud na danou osobu zatím žádný vůz napsán nebyl. Pokud je již vůz napsán u jiné osoby nebo osoba vůbec není uložena jako resident, je vrácen první argument nezměněn. Pokud je jako nový samohyb předána hodnota Nothing, odebere jakýli vůz přiřazený k dané osobě z databáze residentů.

deleteResident #

Arguments

:: Residents

residenti

-> Person

osoba odstanuvší se residentem

-> Residents 

Odstraní osobu (a s ní asociovaný samohyb) z residentů. Pokud osoba nebyla residentem, je vrácen první argument beze změn.

carPrice #

Arguments

:: Database

městská database

-> Time

aktuální čas

-> Car

samohyb doličný

-> Integer 

Cena, kterou musí zaplatit majitel daného vozidla, aby je mohl odparkovat v této chvíli. Vozidlo lze odparkovat jen tehdy, pokud je hodnota této funkce pro toto vozidlo rovna 0.

Cena se počítá různě podle následujícího:

  • pokud je vůz zapsán na nějakého residenta a stojí v libovolné zóně uložené v databasi, pak je cena rovna 0.
  • pokud vůz v databasi residentů není a stojí v zóně označené jako Visitors, pak je cena rovna délce zaparkování, tedy {aktuální čas} – {čas zaparkování}
  • ve všech jiných případech je vůz pokutován a cena se tedy rovná pokutě, ke které je přičtena zvýšená minutová taxa, tedy fine + fineMultiplier * ({aktuální čas} – {čas zaparkování})

payForCar #

Arguments

:: Database

městská database

-> Time

aktuální čas

-> Car

samohyb doličný

-> Parked 

Nastaví dobu parkování tak, aby aktuální cena za parkování (carPrice) byla rovna 0. Může pro tento účel nastavit čas zaparkování i do budoucnosti.

Tedy nastaví čas zaparkování samohybu na:

  • aktuální čas, pokud samohyb není zatížen pokutou,
  • aktuální čas + fine `div` fineMultiplier, pokud zatížen pokutou je.

unparkCar #

Arguments

:: Database

městská database

-> Time

aktuální čas

-> Car

samohyb doličný

-> Parked 

Odebere automobil z database zaparkovaných vozidel, pokud je za něj uhrazen příslušný poplatek za parkování či příslušná pokuta, tedy jeho carPrice je rovna 0.

fines #

Arguments

:: Database

městská database

-> Parked 

Vrátí databasi zaparkovaných vozidel ochuzenou o vozidla, která NEJSOU pokutována (vrátí tedy právě ta pokutovaná).

visitors #

Arguments

:: Database

městská database

-> Parked 

Vrátí databasi zaparkovaných vozidel ochuzenou o vozidla, která NEJSOU zatížena BĚŽNÝM poplatkem za parkování (nikoliv pokutou).

potential #

Arguments

:: Database

městská database

-> Time

aktuální čas

-> Integer 

Vrátí množství peněz, které by připutovaly do městské pokladnice, pokud by za všechna aktuálně zaparkovaná vozidla byly v aktuální chvíli zaplaceny všechny pokuty a poplatky, kterými jsou ta která vozidla zatížena.

interactive #

Arguments

:: Database

počáteční městská database

-> Time

počáteční čas

-> IO (Database, Time, Money) 

Interaktivní přístup k městské databasi mající následující funkce:

  • Je lze ho ukončit.
  • Zvýší čítač času o 1 a zobrazí nový čas.
  • Výpočet množství peněz, které by připutovaly do pokladnice při okamžitém zaplacení všech pohledávek (vizte potential).
  • Zaparkování vozu v dané zóně. Zóna nemusí existovat, v tom případě bude vypsáno upozornění o pokutě. Stejně tak, pokud osoba je návštěvníkem a parkuje v residentské zóně. Nedovolí zaparkovat vůz, který již zaparkován je. Vůz, který není vozem (dle createCar) zaparkován nebude!
  • Zaplacení poplatku/pokuty za zaparkované vozidlo. Vypíše, kolik bylo zaplaceno. Ošetřete neexistenci vozidla.
  • Odparkování vozu. Bude provedeno pouze tehdy, pokud vozidlo není zatíženo poplatkem, ani pokutou (uživatel bude informován, zda bylo vozidlo odparkováno). Ošetřete neexistenci vozidla.
  • Výpis všech dostupných informací, tedy:

    • aktuální čas
    • peníze doposud utržené
    • výpis residentů seřazených podle čísel OP
    • výpis zaparkovaných vozů a jejich aktuální hodnota (vizte carPrice)
  • „Odtah“ všech pokutovaných vozidel, do utržených financí se započítají pokuty a navíc 100 peněz za odtah každého jednoho vozidla.

Provedení libovolné funkce krom čekání netrvá žádný čas.

Funkce vrací nový stav database, nový čas a peníze utržené za zaplacení pokut a parkovacích poplatků za dobu běhu interaktivního asistentu.