Má Haskell budoucnost?

Re:Má Haskell budoucnost?
« Odpověď #405 kdy: 20. 05. 2016, 19:43:45 »
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?
Kód: [Vybrat]
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

Kód: [Vybrat]
f :: Int -> String -> String

a f aplikuju na integer, dostanu:

Kód: [Vybrat]
g :: String -> String

...takze je to vlastne

Kód: [Vybrat]
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:

Kód: [Vybrat]
filter :: (a -> Bool) -> [a] -> [a]

myFilter = filter (\x -> True)

by clovek nenavykly na "automatickou" currifikaci napsal spis takhle:
Kód: [Vybrat]
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:
Kód: [Vybrat]
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):
Kód: [Vybrat]
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:
Kód: [Vybrat]
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 ;)
« Poslední změna: 20. 05. 2016, 19:45:49 od Mirek Prýmek »


Re:Má Haskell budoucnost?
« Odpověď #406 kdy: 20. 05. 2016, 19:50:11 »
Bohuzel (pokud se nepletu) Haskell umoznuje pouzit stejne jmeno pro oboji (neni to konflikt):
Tak nepletu:
Kód: [Vybrat]
Prelude> data Test a = Test a

Prelude> :t Test
Test :: a -> Test a

Prelude> :k Test
Test :: * -> *
Tohle mi neprijde jako stastna volba. Minimalne zacatecniky to muze pekne mast.

Kit

Re:Má Haskell budoucnost?
« Odpověď #407 kdy: 20. 05. 2016, 20:18:22 »
1. promenne nejsou promenne ve smyslu imperativnich jazyku ...
2. v Haskellu plati referencni transparentnost ...
3. V Haskellu funguje currifikace "automaticky" ...
4. pravidla zapisu operatoru - "symboly" jsou defaultne infixove, "slova" prefixova....
5. Type konstruktor neni data konstruktor.  Data konstruktor je normalni funkce...
6. Definice data konstruktoru i type konstruktoru muzou pouzivat promenne obdobne jako definice jinych fci...
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 ;)

Body 1. a 2. jsem pochopil téměř ihned, protože v XSLT je to podobné. 3. - s currifikací se budu muset ještě trochu porvat. 4. bod jsem pochopil z webových stránek. 5. jsem zkoušel, ale teď teprve vím, že "data" je jen funkce a začíná mi to dávat logiku. 6. mi z toho vyplývá. 7. je mi jasná již z předchozích komentů v tomto vláknu.

Takže díky, zbývá mi jen zkoušet a pilovat různé kombinace toho, co jsem se (nejen) tady dozvěděl.

Re:Má Haskell budoucnost?
« Odpověď #408 kdy: 20. 05. 2016, 21:22:10 »
5. jsem zkoušel, ale teď teprve vím, že "data" je jen funkce a začíná mi to dávat logiku.
"data" samo o sobě je klíčové slovo, ne funkce. To, o co jde, je, že data contructor je vlastně funkce. Když mám třeba
Kód: [Vybrat]
Prelude> data MujParadniTyp = PismenkovaHodnota String | CiselnaHodnota Int
tak máme vlastně dvě funkce, které mi ze Stringu nebo Intu vytvoří MujParadniTyp
Kód: [Vybrat]
Prelude> :t PismenkovaHodnota
PismenkovaHodnota :: String -> MujParadniTyp

Prelude> :t CiselnaHodnota
CiselnaHodnota :: Int -> MujParadniTyp
- v podstatě tu hodnotu zavřou do krabice. Krabice může obsahovat String nebo Int hodnotu a krabice samotná má typ MujParadniTyp. V pythonu by se pro podobnej efekt použil tuple:
Kód: [Vybrat]
("PismenkovaHodnota","hola hola")
("CiselnaHodnota",1)
by odpovídalo Haskellovskému
Kód: [Vybrat]
(PismenkovaHodnota  "hola hola")
(CiselnaHodnota 1)
- v Haskellu se krabice prostě dá udělat funkcí a můžu pak dělat pattern matching, to by ve většině jazyků nešlo - funkce je pro ně něco, co jde jenom spustit. Pro Haskell ne :)

A tohodle "zavírání do krabic" se právě chytře používá mj. v těch monádách. A protože krabice i její obsah je vždycky haskellovský typ, tak ta funkce CiselnaHodnota je ze stejné kategorie do stejné kategorie a je to ... tramtadadá! ... ten slavný endofunktor! :) (EDIT: teda respektive byl by, pokud by byl nadefinovaný pro libovolný typ, ne jenom pro String)
« Poslední změna: 20. 05. 2016, 21:30:36 od Mirek Prýmek »

andy

Re:Má Haskell budoucnost?
« Odpověď #409 kdy: 20. 05. 2016, 22:05:54 »
Pár praktických detailů, které mě potrápily:

Aplikace funkce má nejvyšší prioritu. Vždycky. Všude. Tzn.

Kód: [Vybrat]
a b c !!> x y z <* u e >> z p p
je
(a b c) !!> (x y z) <* (u e) >> (z p p)

A funktory se závorkují následovně:
Kód: [Vybrat]
f <$> a <*> b <*> c
je
((f <$> a) <*> b) <*> c


Re:Má Haskell budoucnost?
« Odpověď #410 kdy: 21. 05. 2016, 10:15:01 »
Aplikace funkce má nejvyšší prioritu. Vždycky. Všude. Tzn.
Ono je to bohužel složitější. Je to spíš tak, že operátor (bez závorek) nemůže být argumentem funkce.

Kód: [Vybrat]
list = map foo $ xs
není
Kód: [Vybrat]
list = (map foo $) xs
což by muselo být, pokud by platilo to, co píšeš.

(příklad z http://stackoverflow.com/questions/3125395/haskell-operator-vs-function-precedence)

Haskell sice příjemně snížil nutnost psaní závorek, ale za cenu mírného zmatení. Je to ale o zvyku. Elixir to má taky, jenom trochu jinak.

andy

Re:Má Haskell budoucnost?
« Odpověď #411 kdy: 21. 05. 2016, 10:45:17 »
Aplikace funkce má nejvyšší prioritu. Vždycky. Všude. Tzn.
Ono je to bohužel složitější. Je to spíš tak, že operátor (bez závorek) nemůže být argumentem funkce.
Když jsem to psal, tak jsem přemýšlel, jak to napsat správně... pak jsem to vzdal a radši jsem napsal ten příklad :)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Haskell budoucnost?
« Odpověď #412 kdy: 21. 05. 2016, 17:56:33 »
5. jsem zkoušel, ale teď teprve vím, že "data" je jen funkce a začíná mi to dávat logiku.
"data" samo o sobě je klíčové slovo, ne funkce. To, o co jde, je, že data contructor je vlastně funkce. Když mám třeba
Kód: [Vybrat]
Prelude> data MujParadniTyp = PismenkovaHodnota String | CiselnaHodnota Int
tak máme vlastně dvě funkce, které mi ze Stringu nebo Intu vytvoří MujParadniTyp
Kód: [Vybrat]
Prelude> :t PismenkovaHodnota
PismenkovaHodnota :: String -> MujParadniTyp

Prelude> :t CiselnaHodnota
CiselnaHodnota :: Int -> MujParadniTyp
- v podstatě tu hodnotu zavřou do krabice. Krabice může obsahovat String nebo Int hodnotu a krabice samotná má typ MujParadniTyp. V pythonu by se pro podobnej efekt použil tuple:
Kód: [Vybrat]
("PismenkovaHodnota","hola hola")
("CiselnaHodnota",1)
by odpovídalo Haskellovskému
Kód: [Vybrat]
(PismenkovaHodnota  "hola hola")
(CiselnaHodnota 1)
- v Haskellu se krabice prostě dá udělat funkcí a můžu pak dělat pattern matching, to by ve většině jazyků nešlo - funkce je pro ně něco, co jde jenom spustit. Pro Haskell ne :)

A tohodle "zavírání do krabic" se právě chytře používá mj. v těch monádách. A protože krabice i její obsah je vždycky haskellovský typ, tak ta funkce CiselnaHodnota je ze stejné kategorie do stejné kategorie a je to ... tramtadadá! ... ten slavný endofunktor! :) (EDIT: teda respektive byl by, pokud by byl nadefinovaný pro libovolný typ, ne jenom pro String)
Teď jsi to napsal trochu zmateně a nejsem si jist, že úplně správně.

Re:Má Haskell budoucnost?
« Odpověď #413 kdy: 21. 05. 2016, 17:58:10 »
Teď jsi to napsal trochu zmateně a nejsem si jist, že úplně správně.
Proč zmateně a včem myslíš, že ne správně? (nehádám se, je to možný, proto mě to zajímá)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Haskell budoucnost?
« Odpověď #414 kdy: 21. 05. 2016, 18:16:37 »
Teď jsi to napsal trochu zmateně a nejsem si jist, že úplně správně.
Proč zmateně a včem myslíš, že ne správně? (nehádám se, je to možný, proto mě to zajímá)
Matoucí mi přijde říkat tomu funkce, je to spíš "něco jako" enum s dodatečnými daty (ostatně ve Swiftu to je oficiálně enum). Pak se taky lépe vysvětluje pattern matching.
U té správnosti si nejsem jistý, protože podrobně neznám Haskell, třeba to v něm funkce je, ale obecně to v FP neplatí.

Re:Má Haskell budoucnost?
« Odpověď #415 kdy: 21. 05. 2016, 18:43:27 »
Matoucí mi přijde říkat tomu funkce, je to spíš "něco jako" enum s dodatečnými daty (ostatně ve Swiftu to je oficiálně enum). Pak se taky lépe vysvětluje pattern matching.
U té správnosti si nejsem jistý, protože podrobně neznám Haskell, třeba to v něm funkce je, ale obecně to v FP neplatí.
Mně právě přijde rozumný se na to dívat jako na funkci - nevím o tom, že by někde šla použít funkce a ne data contructor (tím neříkám, že to neexistuje, jenom o tom nevím). U speciálního typu i Haskell wiki mluví o funkci:
Citace
Smart constructors are just functions
https://wiki.haskell.org/Smart_constructors

Dalo by se data konstruktor od normální funkce odlišit, ale moc nevím, k čemu by to bylo dobrý. Naopak neodlišovat to mi přijde fakt elegantní, páč pak můžeš s klidem udělat třeba:
Citace
Prelude> map Just [1,2,3]
[Just 1,Just 2,Just 3]
Teď z hlavy si neumím vybavit všechny souvislosti, ale třeba ty monády by se asi ještě zkomplikovaly, kdybys tu distinkci dělal.

Re:Má Haskell budoucnost?
« Odpověď #416 kdy: 21. 05. 2016, 18:46:13 »
Nebo:
Citace
Value constructors are actually functions
http://learnyouahaskell.com/making-our-own-types-and-typeclasses

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Haskell budoucnost?
« Odpověď #417 kdy: 21. 05. 2016, 18:49:25 »
Matoucí mi přijde říkat tomu funkce, je to spíš "něco jako" enum s dodatečnými daty (ostatně ve Swiftu to je oficiálně enum). Pak se taky lépe vysvětluje pattern matching.
U té správnosti si nejsem jistý, protože podrobně neznám Haskell, třeba to v něm funkce je, ale obecně to v FP neplatí.
Mně právě přijde rozumný se na to dívat jako na funkci - nevím o tom, že by někde šla použít funkce a ne data contructor (tím neříkám, že to neexistuje, jenom o tom nevím). U speciálního typu i Haskell wiki mluví o funkci:
Citace
Smart constructors are just functions
https://wiki.haskell.org/Smart_constructors

Dalo by se data konstruktor od normální funkce odlišit, ale moc nevím, k čemu by to bylo dobrý. Naopak neodlišovat to mi přijde fakt elegantní, páč pak můžeš s klidem udělat třeba:
Citace
Prelude> map Just [1,2,3]
[Just 1,Just 2,Just 3]
Teď z hlavy si neumím vybavit všechny souvislosti, ale třeba ty monády by se asi ještě zkomplikovaly, kdybys tu distinkci dělal.
Nechci se pouštět do diskuze, fakt Haskell moc neznám. Ale z určitého pohledu to smysl dává, ten poslední příklad je celkem hezký a vlastně to třeba v tom Swiftu píšu stejně de facto podvědomě, aniž bych se nad tím pozastavoval. Za ten příklad u mě máš, jak říkával můj profesor fyziky, "malé bezvýznamné plus" ;)

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Má Haskell budoucnost?
« Odpověď #418 kdy: 21. 05. 2016, 18:51:59 »
Nebo:
Citace
Value constructors are actually functions
http://learnyouahaskell.com/making-our-own-types-and-typeclasses
Když na tím teď tak přemýšlím, tak mě zarazilo, že tomu říkáš endofunktor, ten by měl operovat na jiné úrovni, ale třeba jsem to jen blbě pochopil.

Re:Má Haskell budoucnost?
« Odpověď #419 kdy: 21. 05. 2016, 19:35:45 »
Když na tím teď tak přemýšlím, tak mě zarazilo, že tomu říkáš endofunktor, ten by měl operovat na jiné úrovni, ale třeba jsem to jen blbě pochopil.
No to máš asi pravdu, to byl ukvapenej závěr, jehož problematičnost jsem si hned uvědomil a chtěl poladit tím editem, ale ani tak si nejsem jistej, jestli jsem nenapsal blbost ;)

Pokud bysme měli kategorii haskellovských typů, tak funkce jsou morfismy a datakonstruktorem D můžeš mapovat
Citace
f: a -> b
na
Citace
f: D a -> D b
takže funktor to je a protože i (D a) je haskellovský typ, tak by to měl být endofunktor.

...ovšem pokud přijmeme, že konstruktor je normální funkce, tak se nám to trochu pomotá a nevím, jestli by to pak takhle šlo říct, protože tímpádem by to byl morfismus.

No, hele, s tím si musíš poradit spíš ty, pro mě je to na pokraji mých znalostí ;)