Další purescriptové úkoly
Zadáno v úterý 30. 3.
K odevzdání ve středu 21. 4.
Získat můžete až 62 bodů
Úvod pro všechny
- typ je pojmenovaná skupina hodnot
- druh je pojmenovaná skupina typů
Jinými slovy, každá hodnota má nějaký typ, a každý typ má nějaký druh.
Když se budu ptát na určení detailů nějakého x
chci, abyste mi napsali:
- zda
x
je hodnota nebo typ - jaký přesně má
x
typ či druh
Neúplné určení nebudu uznávat.
Například tedy, pokud bych se ptal na určení detailů f
definovaného jako f x = x + 1
tak chci odpověď:
f
je hodnota,f :: Int -> Int
(nebolif
má typInt -> Int
).
Dejte pozor na detaily: například výraz f 10
je také hodnota, jako f
, ale má už jiný typ — Int
.
Maybe (10 bodů)
Maybe a
je typ s následující definicí:
data Maybe a = Nothing | Just a
Jeho konkrétním příkladem je třeba typ Maybe Number
. Tento typ bychom mohli použít například ve funkci read :: String -> Maybe Number
, která se pokusí z daného stringu vyčíst nějaké číslo; v případě, že tam žádné číslo není, bychom vrátili Nothing
, jinak Just <naparsované číslo>
.
Určete detaily
Maybe
.Určete detaily
Maybe Number
Určete detaily
Nothing
Určete detaily
Just
Vypište z definice výše jména typových(-ého) konstruktorů(-u)
Napište funkci
intToNatural :: Int -> Maybe Int
, která převede celé číslo na (možná) přirozené.Napište funkci
verifyAndAddPassword
, která dosatne nové heslo a nějaký record obsahující údaje o uživateli, ověří platnost nového hesla (pravidla nechám na vás) a pokud je ok, přidá toto heslo jako atributpwd
ke vstupnímu recordu, který jinak nechá nezměněný. Nezapomeňte uvést typ vaší funkce.> verifyAndAddPassword "kratke" {username: "Evžen", age: 21} Nothing > verifyAndAddPassword "superb3zp3cnehesl0" {username: "Evžen", age: 21} Just {username: "Evžen", age: 21, pwd: "superb3zp3cnehesl0"}
Pro vkládání do existujícího recordu použijte funkci insert z Data.Record.
Either (5 bodů)
Either a b
je definovaný následovně:
data Either a b = Left a | Right b
Používá se v podobných případech jako Maybe a
— chceme signalizovat, že se nám výpočet nepovedl, a že nemůžeme vrátit normální hodnotu. Místo nicneříkajícího Nothing
však použijeme Left a
, tedy případ, do kterého můžeme uložit nějakou informaci, většinou chybovou hlášku, která popisuje co přesně se nepovedlo. Případ Right b
se používá podobně jako Just a
.
Určete detaily
Either
Vypište z definice výše jména datových(-ého) konstruktorů(-u).
Představte si, že máme funkci
read :: String -> Either String Number
, která se pokusí načíst ze stringu číslo. Pokud se jí to povede, vrátíRight <to načtené číslo>
, pokud se jí to nepovede, vrátíLeft <chybová hláška>
, například:> read "10.5" Right 10.5 > read "slovo" Left "Error: Can't parse a number from 'slovo'"
Napište funkci
addOneToParsed :: Either String Number -> Either String Number
, která k naparsovanému číslo přidá jedničku, nebo — pokud žádné naparsované číslo nemáme — prostě pošle dál chybovou hlášku zLeft
u. Použijte pattern matching.> addOneToParsed (read "10.5") Right 11.5 > addOneToParsed (read "slovo") Left "Error: Can't parse a number from 'slovo'"
List (5 bodů)
Spojové seznamy jsou definovány následovně:
data List a = Nil | Cons a (List a)
- Vypište z definice všechny datové a typové konstruktory (a označte, který je který)
- Určete detaily věcí z bodu jedna
- Určete detaily výrazu
Cons 1 Nil
- Napište funkci
length
, která vrátí délku seznamu. Nezapomeňte správně určit typ této funkce. - Napište funkci
max
, která ze seznamu čísel vrátí to největší. Bonus: Nahraďte čísla v typu funkce vhodně tak, abymax
fungovala i na jiné typy seznamů.
??? (7 bodů)
Podívejte se na následující definici:
data D a b = D a b
- Vypište datové a typové konstruktory
- Určete detaily věcí z bodu jedna
- K čemu by mohl sloužit typ
D a b
? Vymyslete pro typD a b
lepší název - Definujte typový alias
Point
označující bod v rovině, který bude používat výše definovaný typ - Definujte bod
a
na souřadnicích1, -14
- Definujte typ
Line
, který bude pomocí dvouPoint
ů určovat polohu úsečky.
Semafor (5 bodů)
Podívejte se na funkci :
a funkci cons
v Pursuit. Zkuste napsat funkci z bodu 2 pomocí :
.
- Definujte typ
TrafficLight
, který bude mít všeho všudy pouze tři hodnotyRed
,Green
, aYellow
. - Napište funkci
switchLights :: List TrafficLight -> Maybe (List TrafficLight)
, která dostane 'historii' změn barvy semaforu (poslední barva je první v seznamu, předposlední druhá atp) a vrátí novou 'historii' s novou současnou barvou. Například:> switchLights (Cons Yellow (Cons Green)) Cons Red (Cons Yellow (Cons Green)) > switchLights (Cons Red (Cons Yellow (Cons Green))) Cons Yellow (Cons Red (Cons Yellow (Cons Green)))
Nonempty (30 bodů)
Tento oddíl je nejsložitější, v případě potřeby mi pište své dotazy.
Typ NonemptyList a
, který můžete naimportovat z Data.List.Types
je definován jako
data NonEmptyList a = NonEmptyList (NonEmpty List a)
přičemž typ NonEmpty f a
je definován jako
data NonEmpty f a = NonEmpty a (f a)
- Vypište z definice
NonEmptyList a
typový a datový konstruktor a určete jejich detaily. - Určete detaily výrazu
NonEmpty List a
v definiciNonEmptyList a
- Určete detaily
a
v definici typuNonEmpty f a
? Liší se tyto detaily proa
na levé a na pravé straně definice? - Určete detaily
(f a)
vyskytující se vNonEmpty a (f a)
- Určete detaily
f
v definici typuNonEmpty f a
? Pomohou nám k tomu nějak detailya
a(f a)
z otázky výše? - Vytvořte pro zkoušku
NonEmptyList
obsahující čísla 1, 2, 3. - Podívejte se do dokumentace, co dělá funkce
insert
zData.List
(pozor, funkcíinsert
je několik). Implementujte tuto funkci proNonemptyList a
. - Podívejte se do dokumentace, co dělá funkce
insertBy
zData.List
(pozor, funkcíinsertBy
je několik). Implementujte tuto funkci proNonemptyList a
.