Tippek (kezdő) horror Haskel
Haskell kezdő programozója vagyok, és miközben még mindig emlékszem mindenre, ami szörnyű. És azt akarom írni. Azt kell mondanom, amikor elkezdtem Haskell-t, még mindig nem tudtam gyakorlatilag semmit a funkcionális programozásról, így a nyelvvel párhuzamosan új ötleteket és gondolkodási módokat kellett tanulnom. És valójában nagyszerű volt. És a félelem, ahogy ön tudja, a szemek remekek. Általánosságban elmondhatom, hogy ez a feljegyzés hasznos lehet más kezdőknek. Ebben az ötben érthetetlenül rámutattam az elsőre, de viszonylag egyszerű dolgokról, mikor megértettem, ami legalábbis sokkal könnyebb volt a nyelv elsajátítására.
1. Lambda funkciók
"De mi citromfüvet vagy földi kenyeret nevezzük, ez jobban megerõsíti, mint bármely ember ételét, és sokkal finomabb."
Lambda kifejezés - a "funkciók" lényege a forma kifejezés
Ennek a kifejezésnek az értéke még mindig egy (x) argumentum egyik meg nem nevezett függvénye, amely számolja azt (nevezetesen a pont jobb oldalának kifejezését). A lambda függvényekkel komoly matematikai elmélet kapcsolódik, de a programozási szempontból kulcsfontosságú szó a funkció meghatározásához. Valóban, amikor már korábban lambdákat használtam Pythonban (és szinte minden más modern nyelven léteznek). Pythonban így néz ki:
Nagyon kényelmesek voltak a szűrőben () és csökkenteni (). És általában, szinte mindenhol, ahol a függvény nevét kell argumentumként feltüntetni. A lambda funkcióknak azonban nincsenek nevük, és ezért nevezik anonim (névtelen) funkciónak is. Pitonban gyakran neveket adtam nekik:
Most a neve add_42 jelzi a funkciót. Pontosan ugyanazt az eredményt lehet elérni, ha a funkció meghatározását a szokásos módon írja:
És mi van Haskell-nel? Igen, majdnem ugyanaz. A karakter \ helyettesíti, -> szolgál egy időszak helyett. Mindet együtt írták így:
És még neveket is adhatunk ilyen névtelen funkcióknak, akárcsak Python:
Egyetértek, nagyon hasonlóak.
A Haskell-ban minden funkció egy argumentum funkciója. Először ez korlátozásnak tűnhet, de valójában nagyon praktikus és praktikus ötlet. Az n argumentumok bármelyik függvényét egy argumentum függvényében lehet ábrázolni, az n-1 argumentumok egy másik függvényének visszatérésével. És a tudományban ez az úgynevezett currying. Ez az elgondolás különösen lehetővé teszi, hogy a funkciók csak az érvek egy részét adják át.
Még ezek a lambda funkciókra vonatkozó egyszerű koncepciók már elegendőek voltak a Haskel használatának megkezdéséhez és a példák és magyarázatok nagy részének megértéséhez.
2. Egyenlőségi jel
- Nos, ha nincs értelme - mondta a király -, akkor egy hegy van a vállunkon: nem kell megpróbálnunk megtalálni! Sok munkát takarít meg! És mégis.
Véleményem szerint az egyenlőség (=) a Haskell legfontosabb szimbóluma. A nyelv megértéséhez fontos megérteni. És számomra úgy tűnik számomra, hogy az egyenlőség jelentését nem elég hangsúlyozzák mindenféle tankönyvben. Például ez az egyetlen kulcsszó, amely hiányzik Haskell kulcsszólistájából a wikijáján.
A legfontosabb nyelvektől eltérően, ahol = egy hozzárendelést (vagyis egy műveletet) jelent Haskell-ban, ez azt jelenti, hogy a bal oldali egyenlő a jobbal (vagyis a tulajdonságot írja le).
Az "egyenlő" nem jelenti azt, hogy "ez lesz". Ez azt jelenti, hogy valami egyenlő valami mással. Mindig. Mint a matematikában. a = b a Haskell-ban azt jelenti, hogy a egyenlő b-vel. a egyenértékű a b-vel.
Így a = a Haskell-ben írja le a definíciókat. Az "egyenlőek" különböző dolgokat azonosítanak, de statikusan definiálják őket. Nem függ a műveletek sorrendjétől. Bízhatsz benne.
A funkcionális nyelvhasználók számára ez túl nyilvánvalónak tűnik, de éppen az egyenlőség jele szerint a legfontosabb változás az, aki korábban az imperatív nyelveket használta. Most, egyébként neveket adhatunk a névtelen funkcióknak:
Bevallom, hogy rosszul olvasható, ezért a legtöbb esetben a Haskell funkciói a következők:
De ez még mindig az add függvény meghatározása.
3. A típusok osztályai
Jelentős előnyök származnak egy közös típusú rendszer megosztásáért, egy közös eszköztár és így tovább. Ezek a technikai lehetőségek olyan fontos gyakorlati előnyöket jelentenek, mint a mérsékelten eltérő szükségletű csoportok. - a B. Straustrupu-nak tulajdonított
A Haskell típusú rendszer egyszerűen szép. Számos ötletet nagyon könnyen és természetesen fejez ki. És lehetséges, hogy a típusosztályok a legkevésbé idegen fogalmak azok számára, akik egy procedurális és tárgyorientált világból érkeznek Haskellbe. Mindenesetre úgy gondoltam. Azonban a típusosztályok egyáltalán nem ugyanolyanok, mint a C ++ vagy Java osztályok. Sokkal inkább hasonlítanak az absztrakt osztálymintákhoz a C + + -hoz, mert típusosztályok- csak az absztrakt felületet határozza meg
- lehetővé teszik a felület több független megvalósítását (így bármelyik típus esetén egy osztály példányát definiálhatja, ha módszereit végrehajtja)
- polimorf jellegűek és támogatják az örökséget
- nem lehetnek állami változók
Miután hozzászoktunk ahhoz, hogy az osztálytípusok nem C ++ osztályok, de az absztrakt interfészek és az osztályok példái nem "objektumok", hanem az absztrakt interfészek konkrét implementációja, a Haskell azonnal ismertté és hangulatosvá válik.
Erősen javaslom olvasni a Wiki cikket OOP vs type classes. amely sokkal részletesebben összehasonlítja az objektumorientált megközelítést és az osztálytípusú megközelítést.
És mivel egy egyszerű anyag minden jelenlegi állapota természetesen a korábbi állapotának következménye, a jelen el van látva a jövővel - Leibniz, a "monadológia"
Nem számít, mennyire lágy a bevezetése a Haskell-nek. előbb-utóbb olvasója homlokát egy monád erős falán nyugszik. Igen, nem az Ön számára, hogy dörzsölje zsemleket, komoly matematika az Ön számára. Valahol ezen a falon.
De ez az, amit rájöttem: az absztrakt matematikának tanulmányozása nem szükséges a monádok használatához, és nagyon elegáns programozási technikák. Először kissé furcsának tűntek nekem, de a monádok egyszer és mindenkorra való megértése sokkal könnyebb, mint emlékezni (és helyesen alkalmazni!) Az OO design számtalan mintája. A monádok sokkal logikusabbak.
Mivel sok a monádra vonatkozó oktatóanyag, nem fogom megismételni őket, és elvárják, hogy már olvasson párat. Mi a baj a monádokkal? Az imperatív nyelvhez hozzászokott ember számára, amelyet az évek tárgyorientált gondolkodása torzít, a monádok furcsának tűnnek. Olyan, mint egy absztrakt konténerosztály titokzatos módszerrel >> =:
Nos, ha a visszatérés építő, akkor miért ilyen csodálatos név? Ha ez egy konténerosztály, hogyan kell kivonni valamit? És mi a funkció használata a tartályon belül (ez az, amire a metódus >> = szintén a kötési műveletnek nevezhető), ha nem kapjuk meg az eredményt a tartályból?
Először válaszolok az utolsó kérdésre. Miért kell megkötni (>> =)? A monádok egyidejűleg nem konténerek. Ezek csomagolások, csomagok a számításokhoz. nem az értékekhez (visszatérés). Azonban nem számolják ki a számításokat annak érdekében, hogy kényelmesebben tárolják a monádikus dobozokban, de kényelmesebben összekapcsolhatók egymással. A "dobozok" helyett képzeld el a közönséges téglákat, amelyek egymáshoz laposan helyezkednek el. Ez egyébként hasonló az OO-design Adapter-mintájához. Minden egyes monád meghatároz egy módot az eredmény átvitelére egy számításból egy másikba, és végrehajtja a szabványos felületet a módszer használatához (>> =). És bármi történik is, az eredmény mindig ugyanabban a monádban marad (még akkor is, ha meghibásodik, sikertelen).
A monádok nagyon hasonlítanak egymásra. >> = a belső számítást a baloldali monádból veszi, és a jobb oldalon lévő számítással helyettesíti, ami mindig egy másik azonos típusú monádot hoz létre.
A legtöbb nyelv esetében a visszatérés a számítás eredményét a függvényből adja vissza. Haskellben monádok tervezője. Ez nagyon furcsa. Lássuk azonban, hogyan működik >>. ez a művelet megkapja az értéket a baloldali monádból, majd a funkció argumentumához kapcsolja jobbra (így egyébként a másik módszer neve bind). És a jobb oldali függvénynek vissza kell adnia az értéket a monádnak, hogy a rádiót a következő műveleten túl lehessen adni. Ez az első mnemonikus szabály: visszatérés - visszaadja a számított értéket a monádnak.
A második mnemonika. A Haskell bármelyik programjának legfelső szintű funkciója az IO monádon fut (a főfunkció típusa IO ()). Ez a monád lehetővé teszi az I / O végrehajtását és általában az egymást követő műveleteket. Így a monádikus kódot a program legmagasabb szintjén hajtják végre, és szükség szerint "tiszta" kódot hív fel, és nem fordítva. Így bármely "tiszta" érték, ha nem dobja el, akkor előbb-utóbb visszatér a monadhoz, aki ezt hívta.
Remélem, hogy ezek után a magyarázatok után a monádikus konstruktor visszaküldési neve már nem olyan furcsa. Én azonban nem állítom, hogy magyarázataim 100% -osan technikailag helyesek.
Következtetés monádokra
Tehát a kötés (>> =) lehetővé teszi a különböző monádikus számítások kombinálását. Majdnem mindenütt, ahol van egy számítási láncolat, a monádok nagyon alkalmasak. A monádok konkrét megvalósítása különböző szabályokat tartalmazhat a számítások kombinálásához. A visszatérési mód neve elrontja a kezdőket, ez a módszer visszaadja a számítás eredményét a monádnak, és nem a monádnak. Általában, amikor megértettem ezeket az egyszerű ötleteket, ez nagyban segített.
5. Ijesztő szavak
Csak azt tudom, hogy nem tudok semmit.
Még hónapokkal azután is, hogy elkezdtem megtanulni Haskell-ot, tudván, hogy hogyan írhatok hasznos programokat rajta, a Haskell világában több olyan fogalmat találok, amelyekről nem tudok semmit, vagy csak nagyon bizonytalan ötletem. Ezt a fogalmat "szörnyű szavaknak" nevezem. És látom, hogy vannak olyan emberek, akik olyan könyvtárakat hoznak létre és használnak, amelyek ezeket a fogalmakat testesíti meg az életben.
Nyilvánvaló, hogy a Haskell továbbra is a kutatók tesztelési helyszíne. És ez jó és rossz is. Ez jó, mert azt az érzést adja, hogy a tudomány és a technológia legmodernebb élvonalai nagyon közel vannak, és ha kívánatos, akkor új megközelítéseket is kihasználhat. Kívánt esetben. És ugyanakkor rossz, mert amikor új elegáns könyvtárat szeretne használni, kiderül, hogy aktívan használja az ismeretlen és nem teljesen érthető ötleteket, és készen kell álljon arra, hogy elsajátítsa ezeket az ötleteket.
Például van egy modern HXT XML könyvtár. Rengeteg nyilat használ. A nyilak sokoldalúbb számítási számítógépek, mint a monádok, de sokkal többet vettem igénybe, hogy többé-kevésbé megértsem őket. Szigorúan szólva, a nyíl nem része a nyelvnek, de ez a fogalom, amelyet a nyelvhasználók használnak. És sok ilyen példa van. Bár azok, akik nem akarnak nyilakat tanulni, használhat egy hagyományosabb és aktívan támogatott XML-könyvtár HaXml-et.
Fontosnak tartom, hogy ne félj a "szörnyű szavaktól". Szerencsére az alapvető ötleteket jól leírták. Általánosságban vannak olyan cikkek, amelyek részletesen magyarázzák őket. Én magam úgy döntöttem, hogy az ilyen ötleteket szükség szerint elsajátítják. Megígérte, hogy lenyűgöző és ugyanakkor megvalósítható.
következtetés
Öt egyszerű ötletet soroltam fel, miután elsajátítottam őket, könnyebbé vált hozzám szokni Haskellhez. A lambdák csak írási funkciók, és több argumentum funkciója mindig egy függvényként írható be, egy másik függvény visszaküldésével. Az osztálytípusok nagyon hasonlítanak az objektumorientált megközelítés absztrakt polimorf interfészeihez. A monádok egy egységes módja a számítások összekapcsolásának. Szörnyű szavak - szörnyű szavak. Nem élhetsz nélküle, de unalmas.
Remélem, hogy jegyzeteim hasznosak lehetnek valakinek.