Funkcionalno programiranje (Haskell)

poruka: 37
|
čitano: 11.561
|
moderatori: Lazarus Long, XXX-Man, vincimus
+/- sve poruke
ravni prikaz
starije poruke gore
16 godina
neaktivan
offline
Funkcionalno programiranje (Haskell)

Upravo to, monade Haskelasi zovu "programmable semicolon" jer implementacija samog monada odlucuje kako ce se bind izvrsiti, odnosno kako ce se i da li ce se slijedeca funkcija izvrsiti.

U slucaju Maybe tipa, koji ima ili vrijednost Just x (gdje je x neka vrijednost) ili Nothing, monadski bind sa pattern matchingom izgleda otprilike ovako:

 

f >>= Nothing = Nothing
f >>= (Just a) = Just (f a)

 

Dakle, ako bindamo instancu Maybea na neku funkciju, ovaj bind odlucuje sto ce se dogoditi. U slucaju da Maybe sadrzi Nothing, matcha se prvi pattern, funkcija se ne izvrsava i Nothing se jednostavno propagira dalje. U slucaju da Maybe sadrzi Just vrijednost, onda bind vraca novu Just vrijednost gdje se bindana funkcija aplicira na 'a'.

 

Super korisno, pogotovu ako se npr. umjesto Maybe koristi Either, koji je dvostruko tipiziran (odnosno nosi vrijednosti Left a i Right b, umjesto samo Just a i Nothing), a principijelno se koristi da bi propagirao gresku a ne samo nedostatak vrijednosti kao Maybe.

Vrlo slicno Maybeu, Either propagira Right (igrajuci se rijecima s cinjenicom da Right osim desno, znaci takodjer i i 'ispravno') aplicirajuci funkcije, dokle se Left samo propagira.

 

I ono najbitnije - monade za svoje tipove podataka implementiras sam, odnosno sam odlucujes kako ce se koji bind ponasati za koji konstruktor.

 

P.S.

Zanimljivo silovanje monada u Haskellu - tip je implementirao BASIC DSL Monad :-D

http://augustss.blogspot.ca/search/label/BASIC

 

Kako ja to zamisljam, njegov Basic data sadrzi state cijele BASIC masine, a svaki BASIC statement je monadska funkcija koja binda novo stanje na slijedecu funkciju.

Ono sto ne kuzim jest kako je sredio brojevne linije, ali kaze da su u pitanju ekstenzije compilera.

Are you looking at me? Why do you keep looking at me? Am I not merciful? Am I not - merciful...
Poruka je uređivana zadnji put čet 26.5.2016 20:59 (Deus ex machina).
 
0 0 hvala 0
17 godina
offline
Funkcionalno programiranje (Haskell)

Ima li u Haskellu pandan sugar implementaciji monada u F#.

Po tom sugar konceptu monad definiram u klasi , a instancu te klase koristim za implementciju monada na jednostavan način.

Realno, ne bi mogao zamisliti da u implementaciji monada uvezujem više od tri funkcije bez da koristim ovaj sugar koncept.

Mada korištenje ovog layera zamagljuje stvari, pa se izgubi bit kako stvari funkcioniraju, praktično itekako jest.

Poruka je uređivana zadnji put pet 27.5.2016 11:56 (Floki).
 
0 0 hvala 0
16 godina
neaktivan
offline
Re: Funkcionalno programiranje (Haskell)
Floki kaže...

Ima li u Haskellu pandan sugar implementaciji monada u F#.

Po tom sugar konceptu monad definiram u klasi , a instancu te klase koristim za implementciju monada na jednostavan način.

Realno, ne bi mogao zamisliti da u implementaciji monada uvezujem više od tri funkcije bez da koristim ovaj sugar koncept.

Mada korištenje ovog layera zamagljuje stvari, pa se izgubi bit kako stvari funkcioniraju, praktično itekako jest.

 Ako sam dobro shvatio, radi slicno. Postoji Monad typeclass koja je parameterizirana s jednim tipom, koji mora biti kind * -> * (sto znaci nekonkretan tip, vec tipiziran s jednom type variablom). Maybe je dobar primjer, jer Maybe je parameteriziran s jednim tipom zbog Just konstruktora (tako da primjerice Maybe Int moze biti ili Nothing, ili Just <int>).

 

Typeclass se ponasa otprilike kao interface u OOP-u, tj. definiras samo tipove funkcija. Nakon toga, kad zelis instancirati da neki tvoj data type bude Monad, negdje gdje 'vidis' i Monad typeclassu i tvoj datatype, napravis instancu

 

instance Monad TvojType where
   a >>= b = ....
  return  = ....

 

Ovaj >>= operator je bind funkcija.

 

Da li ima u F#-u nesto kao do-notacija za monade u Haskellu?

U Haskellu mozes monadsku vrijednost ispisivati skoro kao imperativni code, primjerice:

 

main :: IO ()
main = do
    x <- getLine
    putStrLn $ "Foo: " ++ x

 

sto je potpuno jednako kao:

 

main :: IO()
main = getLine >>= putStrLn . ("Foo: "++)

 

putStrLn prima String i vraca IO (), njega komponiram s operatorom ++, koji prima dva parametra ali je ovdje parcijalno apliciran s lijeve strane jednim parametrom i prima String. getLine vraca IO String, ali s obzirom da je IO monad, bindanjem propagira "cisti" String (ili exception).

 

 

Edit:

sad bas gledam, sugar syntax je u F#-u ista stvar kao do-notation u Haskellu :-)

Are you looking at me? Why do you keep looking at me? Am I not merciful? Am I not - merciful...
Poruka je uređivana zadnji put pet 27.5.2016 14:48 (Deus ex machina).
16 godina
neaktivan
offline
Funkcionalno programiranje (Haskell)

Odlican article koji objasnjava funktore, aplikativne funktore i monade kroz slike i tekst:

 

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

 

Takodjer, na njegovom siteu se daju pronaci slicni tutoriali o primjerice multithreadingu na razlicite nacine (locks, actors, software transactional memory)

 

Edit:

malen dodatak - odlican SO odgovor na temu "Zasto su monadi mocniji od aplikativnih funktora".

http://stackoverflow.com/questions/23342184/difference-between-monad-and-applicative-in-haskell

Are you looking at me? Why do you keep looking at me? Am I not merciful? Am I not - merciful...
Poruka je uređivana zadnji put pon 30.5.2016 15:57 (Deus ex machina).
 
0 0 hvala 1
16 godina
neaktivan
offline
Funkcionalno programiranje (Haskell)

Lens - sigurnije i kvalitetnije imperativno programiranje nego u, uhm, imperativnim jezicima :-D

 

Odlican crash course:

http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html

You need another death just to have a life to save - you need a master just so you can beg - you need a light just because you&#39;re so afraid - now bow, and learn to be a good slave...
 
0 0 hvala 0
15 godina
offline
Re: Funkcionalno programiranje (Haskell)

Java

class Whatevs {
   public static void main(String[] args) {
     List<Integer> l = Arrays.asList(new int[] {0,1,2,3,4,5,6,7,8,9});
     List<Integer> o = new ArrayList(l.size());
     for (int v : l)
       o.add(v + 2);

   }
}

 

Haskell 

main = (_ -> map (+2) [0..9]) >> return ()

 

 Moze to u Javi malo jednostavnije

List<Integer> l = Arrays.asList(0,1,2,3,4,5,6,7,8,9));
l.stream().map(x->x+2).collect(Collectors.toList());

//Ili ako cemo bas cjepidlacit, moze i ovako :D

List<Integer> l = Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream().map(i->i+2).collect(Collectors.toList());

Poruka je uređivana zadnji put čet 27.10.2016 17:51 (passat).
16 godina
neaktivan
offline
Re: Funkcionalno programiranje (Haskell)
passat kaže... 

 Moze to u Javi malo jednostavnije

List<Integer> l = Arrays.asList(0,1,2,3,4,5,6,7,8,9));
l.stream().map(x->x+2).collect(Collectors.toList());

//Ili ako cemo bas cjepidlacit, moze i ovako :D

List<Integer> l = Arrays.asList(0,1,2,3,4,5,6,7,8,9).stream().map(i->i+2).collect(Collectors.toList());

Naravno da se moze. Moze se i u Javascriptu, i u C++u, i u Pythonu. No samo zato jer se moze, ne znaci da bi i trebalo - Java postaje (los) multiparadigm jezik. Map, collect (odnosno, fold ili reduce) su funkcijski termini i u OOP-u nemaju sto traziti (malo dolje objasnjavam zasto).

Moj example je cisti OOP code, kakav javac ocekuje ako se trazi brz bytecode. Primjeti takodjer da namjerno nisam izostavio definiciju static void main niti definiciju klase - to postoji zato jer vjerujem da je bitno uvidjeti da Java ima visoko "trenje" kad pises code, koje je nastalo iz davnih dana kad je java bila striktni OOP jezik. Iz istog razloga, nisam izostavio ni definiciju main iz Haskella, gdje je neophodno liftati map (+2) [0..9] u lambdu i bindati na return ().

Ako maknes klasu i main u javi, onda paralelno Haskell code postaje doslovce map (+2). Ne treba ti ni [0..9] jer map (+2) zbog curryinga postaje funkcija koja prima bilo koju listu.

 

Sintaksa je, takodjer, povrsan nacin usporedbe jezika. To sto Haskell uglavnom ima cistiju sintaksu ne govori ama bas nista o kvaliteti jezika, jer onda bi C bio najbolji jezik na svijetu, a C++ templateovi najlosiji izum ikad - a ni jedno ni drugo nije istina.

Ono sto vrijedi usporediti su kvalitete kao npr. osjetljivost na promjene, striktnost compilera, otvorenost prema refaktoriranju, modularnost. Java, kao i ostali OOP te imperativni jezici u tome opcenito ima los score jer OOP paradigma prije svega ohrabruje enkapsulaciju koja po definiciji stvara code nestabilan za promjene, a kao drugo nije dobro prilagodjena konkurentnom programiranju.

Takodjer, Java je jezik koji ovisi o globalnom stanju (kao i velika vecina popularnih funkcijskih jezika danas, npr. Scala, Clojure i Erlang) sto znaci da slijed naredbi *ima* veze s time kako ce se program razvijati, i znaci da apsolutno svaka funkcija moze imati side-effecte - sto znaci da mozes funkcijsku paradigmu maltene baciti kroz prozor, i pokupiti samo shortcutove kao sto su lambde i sintakse za liste da si olaksas pisanje (sto i nije lose) - ali to vise nije funkcijsko programiranje, takvo sto mozes i sa C precompilerom. To je razlog zasto OOP termini nemaju sto traziti u OOP jeziku.

 

 

 

Za Javu ja uopce nemam nade, nekad pred 10ak godina bila je odlican, brz, stabilan jezik, sa ogromnom platformom i bila je vrhunski odabir za izradu bilo koje aplikacije. Sa samo malo izmjena (rucni cacheing umjesto GC-a, npr.) mogao si napisati aplikaciju koja bi bez problema stala rame uz rame sa C++-om sto se tice performansi, plus nisi morao recompilirati nista nego samo dostaviti JAR i gotovo.

Vremena su se promjenila, danas na to mozes zaboraviti, jer hardware nije kakav je bio pred 10 godina, a i vecina stvari koje trebaju biti portabilne, vrte se u browseru.

Istina, jos uvijek se daju pisati lijepe web aplikacije ali to su vise XML, anotacije i JSON, nego 'istinski' Java code, pa to mozes procesirati vise manje svagdje, a kontinuirani napredak devOPS ideje i mikroplatforme znaci da vrlo skoro nece ni tu vise biti mjesta.

Znam iz bliske stvarnosti firme koje posluju u US i Kanadi koje prodaju SAAS produkt koji je - pazi ovo - doslovce mala hrpica CURL/PERL skripti koja sluzi kao glue izmedju mikroplatformi (dropbox, elastic search, etc).

Java je jako dobro popunila mjesto koje je bilo prazno u proslosti i rijesila te probleme vrlo elegantno. Stvari su se promjenile, neki problemi vise ne postoje, a neki su rijeseni na bolji nacin. Treba Javu pustiti da umre i okrenuti se necemu drugome, ovisno o tome sto covjek zeli raditi u buducnosti.

You need another death just to have a life to save - you need a master just so you can beg - you need a light just because you&#39;re so afraid - now bow, and learn to be a good slave...
Nova poruka
E-mail:
Lozinka:
 
vrh stranice