Kurzusok
/
Elm
Elm
/
Feladatok
/
Trendlovag
Trendlovag

Trendlovag

Tanulófeladat

Bevezetés

Rekordok

A rekordok olyan adatszerkezetek, amelyek címkékkel csoportosítják az összetartozó információkat. Hasonlítanak a JavaScript vagy Java objektumaihoz, illetve a C vagy Rust structjaihoz, de néhány lényeges különbség van köztük.

Rekordok létrehozása

A rekordokat kapcsos zárójelekkel hozzuk létre, az elemeiket pedig vessző választja el.

firefly =
    { name = "Firefly"
    , creator = "Joss Whedon"
    , episodes = 14
    }

A rekord típusát is hasonló szintaxissal definiáljuk, azzal a különbséggel, hogy az egyenlőségjeleket (=) kettőspontok (:) helyettesítik.

firefly : { name : String, creator : String, episodes : Int }
firefly =
    { name = "Firefly"
    , creator = "Joss Whedon"
    , episodes = 14
    }

Ezeket a típusdefiníciókat ismételgetni körülményes, ezért gyakori megoldás, hogy egy típusalias segítségével megosztjuk a definíciót.

type alias TvSeries =
    { name : String
    , creator : String
    , episodes : Int
    }

firefly : TvSeries
firefly =
    { name = "Firefly"
    , creator = "Joss Whedon"
    , episodes = 14
    }

A típusalias emellett automatikusan biztosít egy konstruktorfüggvényt is a rekordhoz. Ez néha meglepő, hiszen az Elmben a függvényeknek kisbetűvel kell kezdődniük, a típuskonstruktorok viszont ez alól kivételt képeznek.

firefly : TvSeries
firefly = TvSeries "Firefly" "Joss Whedon" 14

A rekordok mezőinek elérése

A legfőbb módja annak, hogy hozzáférjünk egy rekordpéldány egyik mezőértékéhez, a pontjelölés használata, például így: firefly.creator. Az Elm fordító emellett támogat olyan speciális elérési függvényeket is, amelyek ponttal (.) kezdődnek, például a .creator, és minden olyan rekordon működnek, amelyben van ilyen nevű mező. Ez a második kivétel az alól a szabály alól, hogy a függvényeknek kisbetűvel kell kezdődniük. Valójában a felhasználó által definiált függvényeknek kisbetűvel kell kezdeniük, de az imént megismert két példát a fordító generálja, nem a programozó.

firefly : TvSeries
firefly =
    { name = "Firefly"
    , creator = "Joss Whedon"
    , episodes = 14
    }

firefly.name
    --> "Firefly"

.creator firefly
    --> "Joss Whedon"

A rekordokat kötéseken belül destrukturálhatjuk is a rekordok mintaillesztésével. A destrukturálás bármely olyan rekordon működik, amelyben megvannak a szóban forgó nevű mezők.

episodesCount : TvSeries -> Int
episodesCount { episodes } =
    episodes

complicatedCopy : TvSeries -> TvSeries
complicatedCopy show =
    let
        { name, creator } = show
    in
    { name = name
    , creator = creator
    , episodes = episodesCount show
    }

Rekordok frissítése

A rekordok változtathatatlanok, ahogy az Elmben minden, így ha egyszer definiáltunk egy rekordot, a mezőértékei soha nem változhatnak meg. Létezik egy speciális szintaxis, amellyel egy meglévő rekord másolatát hozhatjuk létre úgy, hogy egy vagy több mezőjét megváltoztatjuk. Ez a szintaxis a pipe (|) szimbólumot használja, hogy megkülönböztesse az eredeti rekordot a megváltozó mezőktől, például így: { oldRecord | field1 = newValue }.

firefly : TvSeries
firefly =
    { name = "Firefly"
    , creator = "Joss Whedon"
    , episodes = 14
    }

updatedFirefly : TvSeries
updatedFirefly =
    { firefly | creator = "J Whedon", episodes = 15 }

Rekordok összehasonlítása

Az Elm [szerkezeti egyenlőséget][equality] használ, ami azt jelenti, hogy ugyanazon rekord két példánya azonos értékekkel egyenlő.

firefly1 = TvSeries "Firefly" "Joss Whedon" 14
firefly2 = TvSeries "Firefly" "Joss Whedon" 14

firefly1 == firefly2
    --> True

Bővíthető rekordok

Az Elm a szerkezeti típusozást is támogatja, ami azt jelenti, hogy ha egy függvény olyan rekordot vár, amelyben van x és y mező, akkor bármely olyan rekordon működik, amelyben megvannak ezek a mezők, például kétdimenziós pontokon, háromdimenziós pontokon, űrhajókon stb. Ezeknek a rekordtípusoknak a definíciójában szerepel egy pipe (|), például { a | x : Float, y : Float }, és az Elm terminológiájában „bővíthető rekordoknak” nevezzük őket. Ügyelj a különbségre egy típusdefinícióban szereplő pipe (|) között, amely egy bővíthető rekord definíciója ({ a | x : Int }), és egy tényleges rekordpéldányban szereplő pipe (|) között, amely azt jelenti, hogy a rekord néhány mezőjét frissítjük.

point2d = { x = 1, y = 2 }
point3d = { x = 3, y = 4, z = 7 }

.x point2d --> 1
.x point3d --> 3

length : { a | x : Float, y : Float } -> Float
length vector =
    sqrt (vector.x * vector.x + vector.y * vector.y)

length point2d --> 2.236068
length point3d --> 5

translateX : { a | x : Float } -> { a | x : Float }
translateX vector =
    { vector | x = vector.x + 1 }

translateX point2d --> { x = 2, y = 2 }
translateX point3d --> { x = 4, y = 4, z = 7 }

Utasítások

Ebben a feladatban nagy sportrajongó vagy, és épp most fedeztél fel magadban szenvedélyt az NBA kosárlabda iránt. Mivel még új vagy az NBA kosárlabdában, mélyelemzést végzel az NBA történetéből: nyomon követed a csapatokat, az edzőket és a győzelmi/vereség statisztikáikat, és összehasonlítod őket egymással.

Mivel még nincs kedvenc csapatod, egy algoritmust is fejlesztesz majd, amivel eldöntheted, hogy egy adott csapatnak szurkolj-e. Hét részfeladat segít abban, hogy kifejleszd a saját csapatszurkolási algoritmusodat.

1. Definiáld a modellt

Definiáld a Coach típusaliast egy rekordhoz a következő két mezővel, a következő sorrendben:

  • name: az edző neve, típusa String.
  • formerPlayer: jelzi, hogy az edző korábban játékos volt-e, típusa Bool.

Definiáld a Stats típusaliast egy rekordhoz a következő két mezővel, a következő sorrendben:

  • wins: a győzelmek száma, típusa Int.
  • losses: a vereségek száma, típusa Int.

Definiáld a Team típusaliast egy rekordhoz a következő három mezővel, a következő sorrendben:

  • name: a csapat neve, típusa String.
  • coach: a csapat edzője, típusa Coach.
  • stats: a csapat statisztikái, típusa Stats.

2. Hozz létre egy csapatot

Olyan harmadik féltől származó kóddal szeretnél együttműködni, amelynek van egy csapat fogalma, de más sorrendben hívja meg a kódodat a paraméterekkel. Adj hozzá egy createTeam függvényt a következő szignatúrával: String -> Stats -> Coach -> Team.

3. Cseréld le az edzőt

Mivel az NBA-tulajdonosok türelmetlenek, rájöttél, hogy a rossz csapateredmények gyakran az edző lecseréléséhez vezetnek. Valósítsd meg a replaceCoach függvényt, amely paraméterként az új edzőt és a csapatot kapja, és visszaadja a csapatot, de az új edzővel:

let
    coach = { name = "Larry Bird", formerPlayer = True }
    stats = { wins = 58, losses =  24 }
    team = { name = "Indiana Pacers", coach = coach, stats =  stats }
    newCoach = { name = "Isiah Thomas", formerPlayer = True }
in
replaceCoach newCoach team
--> { name = "Indiana Pacers"
--  , coach = { name = "Isiah Thomas", formerPlayer = True }
--  , stats = { wins = 58, losses = 24 } }

4. Ellenőrizd, hogy szurkolj-e egy csapatnak

A jövőben egy bonyolult algoritmust tervezel kidolgozni arról, hogy szurkolj-e egy csapatnak vagy sem, de első próbálkozásként úgy döntöttél, hogy minden olyan csapatnak szurkolsz, amelynek több győzelme van, mint veresége.

Szeretnéd, ha ez a függvény más helyzetekben is újrahasznosítható lenne, ezért használj kiterjeszthető rekordot a típus szignatúrában, hogy bármilyen rekordot elfogadjon, amely rendelkezik a szükséges mezőkkel. Hogy a függvény a lehető legtömörebb legyen, mintázatillesztéssel szeretnéd kinyerni a stats mezőt a függvény paraméteréből. Valósítsd meg a rootForTeam függvényt, amely egy csapatot kap, és True értéket ad vissza, ha szurkolni kell a csapatnak; egyébként False értéket ad vissza.

let
    spursCoach = { name = "Gregg Popovich", formerPlayer =  False }
    spursStats = { wins = 56, losses = 26 }
    spursTeam = { name = "San Antonio Spurs", coach = spursCoach, stats = spursStats }
in
rootForTeam spursTeam
--> True
Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg
Elm Exercism

Készen állsz elkezdeni a(z) Trendlovag feladatot?

Iratkozz fel az Exercism-re, hogy megtanuld és elsajátítsd a(z) Elm nyelvet 28 fogalom110 feladat segítségével, valódi emberi mentorálással, mindez ingyen.