Vaším úkolem je opravit neidiomatický kód v Haskellu.
K dispozici máte style guide (viz níže)
a nástroje v Haskell Language Serveru, konkrétně ghci
, hlint
,
nějaké formátítko se určitě hodí.
Neměňte názvy funkcí (aby to nerozbilo testování),
ani její význam (testy by měly procházet).
Testy se dají spustit napsáním main
v GHCi,
vytvořil jsem dole malý unit testový framework,
abyste si mohli být jisti, že jste nic nerozbili...
Nesnažte se hledat hezké verze těchto funkcí na internetu,
tak nějak to jde proti celému smyslu tohoto úkolu.
Dále nepoužívejte žádné jiné moduly (žádný import
...).
Do komentáře nad každou funkcí napište které zásady ze style guide jste použili (stačí číslo), popřípadě můžete použít i nějaký slovní popis. Pozor, že vám HLS/hlint může nabízet i věci, které vám nedávají smysl a nejsou ve style guide, v tom případě je ignorujte...
Deadline je jako obvykle dva týdny od zadání, tedy do 6. 5. 08:59.
-
Kód musí jít zkompilovat pomocí GHC bez errorů či warningů.
-
Každá top-level funkce musí mít typovou deklaraci.
Místo:
secti x y = x + y
napište:
secti :: Int -> Int -> Int
secti x y = x + y
- Používejte standardní Haskellové názvy:
camelCase
místosnake_case
- pattern match na seznamu je typicky
(x:xs)
či(y:ys)
- vnitřní rekurzivní funkce se často jmenuje
go
- Používejte rozumné názvy:
- top-level funkce by měly mít rozumný, popisný název
- lokální proměnné, které jsou dost obecné mohou být klidně pár znaků
Konkrétně pokud máte xs :: [a]
, tak je to lepší název než seznamAcek :: [a]
,
pokud je to pro nějaké obecná a
(třeba s obecným kvantifikátorem...)
- Používejte konzistentní odsazení pomocí mezer (ne tabů)
- taby jsou dost špatné -- na každém počítači jsou jiné a mixování s mezerami je úplná tragédie
- vyberte si dvě/čtyři/osm mezer a je to :)
- Vyvarujte se extrémně dlouhým řádkům (kolem 100 znaků už je to vopruz číst)
- Používejte whitespace k odsazení, oddělení a zarovnání
- mezi top-level deklaracemi by měla být alespoň jedna prázdná mezera
- hezky zarovnané věci (např. v
case
) jsou fajn, ale není to nutné
- Preferujte stráže (guards) před
if
Například místo:
porovnej a b =
if a > b then "Leva je vetsi"
else if a == b then "Stejne"
else "Prava je vetsi"
použijte:
porovnej a b
| a > b = "Leva je vetsi"
| a == b = "Stejne"
| otherwise = "Prava je vetsi"
- Preferujte pattern matching před projekcemi (
fst
,snd
,(!!)
)
Pattern matching je jednodušší a čistější! Tedy místo:
foo x = ...
where
a = fst x
b = snd x
použijte:
foo (a, b) = ...
Podobně pokud procházíte seznam sekvenčně,
tak raději používejte pattern matching na (x:xs)
místo přístupů stylem xs !! 0
, xs !! 1
, xs !! 2
...
Nezapomeňte, že (!!)
je worstcase O(N)!
- Používejte pattern matching rovnou na parametry funkcí.
Například ten příklad výše pravděpodobně nikde nepotřebuje x
jako takové,
proto dává smysl jej rozbalit.
- Vyvarujte se vnořených
case
ů.
Pokud máte v sobě vícero case
ů, často je chcete spíše zkombinovat do jediného pomocí n-tice.
Tedy místo:
data Barva = Cervena | Zelena | Modra
case a of
Cervena -> case b of
Cervena -> True
Zelena -> False
Modra -> False
Zelena -> case b of
Cervena -> False
Zelena -> True
Modra -> False
Modra -> case b of
Cervena -> False
Zelena -> False
Modra -> True
použijte následující:
case (a, b) of
(Cervena, Cervena) -> True
(Zelena , Zelena ) -> True
(Modra , Modra ) -> True
(_ , _ ) -> False
- Nepoužívejte částečné funkce
Funkce jako head
, tail
, fromJust
jsou takzvaně částečné --
při prázdném seznamu vyhodí error.
To je ale dost nebezpečné a můžete se tím střelit do nohy.
Pokud je to možné, použijte raději pattern matching!
Tedy místo:
foo seznam = ...
where
x = head seznam
xs = tail seznam
napište:
foo (x:xs) = ...
- Nepoužívejte zbytečné
if
y.
Nepište if
y, které jsou zbytečné!
Například místo:
if b then False else True
použijte:
not b
Nebo místo:
if x then y else False
použijte:
x && y
a tak dále...
Tato style guide je specifická pro tento úkol, reálně by byla o něco obsáhlejší, detailnější a striktnější...
Pokud chcete "opravdovou" style guide, zkuste třeba tuto od Kowainik: https://kowainik.github.io/posts/2019-02-06-style-guide