Tohle byla jedna z prvních věcí, kterou jsem pochopil. Zapomněl jsi však uvést, že "a" je jméno funkce. Kromě toho se "a" používá i jako zástupný symbol typu v definici parametrů. Přesto jsi ho použil jako jméno funkce, abys mi to co nejvíc zamlžil. To je tak těžké napsat tohle?
f a = a + 1
V Haskellu je nekolik konceptu, ktery clovek bezpodminecne musi spravne pochopit, jinak se v dalsim utopi (v nejhorsim pripade si bude myslet, ze to chape, ale pochopi to blbe):
1. promenne nejsou promenne ve smyslu imperativnich jazyku ("misto, kam dam nejakou hodnotu"), ale "nalepky pro hodnoty" - viz
http://stackoverflow.com/questions/29967086/are-elixir-variables-really-immutable (tady se mluvi o Elixiru, ale v Haskellu je to totez). Je potreba rozlisovat volnou a vazanou promennou (tohle je spis prologovska hantyrka, ale funguje to stejne).
2. v Haskellu plati referencni transparentnost = jestlize plati a=b, tak kdekoli mam a, tam muzu dat b, a program bude fungovat porad stejne.
3. V Haskellu funguje currifikace "automaticky" - jestlize mam fci f dvou promennych, tak (f 1) je funkce jedne promenne. V jinych jazycich bych to musel udelat explicitne lambdou: lambda x: f(1,x).
Tohle je taky ten duvod, proc se v typovych anotacich pouzivaji ty divne sipky a ne carky. Kdyz mam treba
f :: Int -> String -> String
a f aplikuju na integer, dostanu:
g :: String -> String
...takze je to vlastne
f :: Int -> (String -> String)
- a ty zavorky je tam zbytecne psat, proto se tam nepisou.
Zaroven je tohle vec, ktera taky zpusobuje horsi citelnost pro lidi zvykly na jiny jazyky, napr:
filter :: (a -> Bool) -> [a] -> [a]
myFilter = filter (\x -> True)
by clovek nenavykly na "automatickou" currifikaci napsal spis takhle:
myFilter list = filter (\x -> True) list
ale haskellisti to nedelaji. Zhorsuje to citelnost, protoze si clovek musi v hlave odvozovat parametry leve strany z prave.
4. pravidla zapisu operatoru - "symboly" jsou defaultne infixove, "slova" prefixova. Symboly se prefixove zapisuji pomoci zavorek, slova infixove pomoci zpetnych apostrofu:
1 + 1 ~ (+) 1 1
filter (\x -> True) [1] ~ (\x -> True) `filter` [1]
5. Type konstruktor neni data konstruktor. Data konstruktor je normalni funkce. Type konstruktor je "funkce o level vys". Bohuzel (pokud se nepletu) Haskell umoznuje pouzit stejne jmeno pro oboji (neni to konflikt):
data Maybe a = Nothing | Just a
Prelude> :t Just
Just :: a -> Maybe a
Prelude> :k Maybe
Maybe :: * -> *
Prelude> :k Just
<interactive>:1:1:
Not in scope: type constructor or class ‘Just’
A data constructor of that name is in scope; did you mean DataKinds?
Prelude> :t Maybe
<interactive>:1:1:
Not in scope: data constructor ‘Maybe’
Perhaps you meant variable ‘maybe’ (imported from Prelude)
6. Definice data konstruktoru i type konstruktoru muzou pouzivat promenne obdobne jako definice jinych fci:
Prelude> :k Maybe
Maybe :: * -> *
Prelude> :k Maybe String
Maybe String :: *
7. I kdyz je do block navrzeny tak, aby vypadal, ze v nem vyse zminene neplati, tak je to jenom syntakticky cukr, ve kterem porad plati vsechno.
---
Kdyz si tyhle veci zazijes, das uz v Haskellu celkem cokoli, s vetsim nebo mensim usilim
