TypeScript Academy · leksjon

Det lettvektsbaserte HKT-mønsteret

Implementer defunksjonaliseringsknepet Kind/URI.

Leksjon 3 av 413 trinn

Det lettvektsbaserte HKT-mønsteret er en gratis leksjon i TypeScript Academy på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i TypeScript Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i TypeScript Academy inneholder totalt 4 leksjoner.

Defunksjonalisering

Trikset bak kodingen har et navn: defunksjonalisering. I stedet for en ekte typefunksjon av høyere orden representerer vi hver funksjon med en tagg og løser den med ett enkelt oppslag av første orden. URItoKind-registeret er denne oppslagstabellen.

type Kind<F extends URIS, A> = URItoKind<A>[F];
// One lookup replaces true type-function application

Kind-typen

Kind<F, A> er det offentlige grensesnittet til mønsteret. Les det som «konstruktøren F anvendt på A». Det skjuler registerindekseringen bak et ryddig navn.

type A = Kind<"Array", number>;  // number[]
type B = Kind<"Option", string>; // string | null

Begrens F til URIS

F må være en registrert URI. Begrens den med extends URIS, slik at bare gyldige tagger kan brukes og skrivefeil blir kompileringsfeil.

type Kind<F extends URIS, A> = URItoKind<A>[F];

// Kind<"Arrey", number> -> error, not a valid URI

Skrive generiske signaturer

Nå kan vi skrive den tidligere umulige Functor-signaturen. Erstatt hver F<A> med Kind<F, A>, så godtar kompilatoren den.

interface Functor<F extends URIS> {
  map<A, B>(fa: Kind<F, A>, f: (a: A) => B): Kind<F, B>;
}

Oppløsning i praksis

Når De binder F til en konkret URI, løses Kind til den faktiske containertypen. En Functor<"Array"> har en map fra A[] til B[].

type ArrayFunctor = Functor<"Array">;
// map: <A, B>(fa: A[], f: (a: A) => B) => B[]

Flere typeargumenter

Noen konstruktører tar to argumenter, for eksempel Either<E, A>. fp-ts utvider mønsteret med URItoKind2 og Kind2<F, E, A> for kind * -> * -> *. Ideen skalerer ved å legge til flere registre.

interface URItoKind2<E, A> {
  Either: { left: E } | { right: A };
}
type Kind2<F extends URIS2, E, A> = URItoKind2<E, A>[F];

fp-ts-konvensjonen

fp-ts etablerte konvensjonen som hele dette kurset følger: én URI-streng per datatype, et URItoKind-register som utvides med deklarasjonssammenslåing, og Kind for oppløsning. Når De kjenner den igjen, kan De lese type-signaturer i fp-ts og Effect.

// In fp-ts you will see exactly:
// declare module "fp-ts/HKT" { interface URItoKind<A> { ... } }

En instanspost

En «instans» av en abstraksjon er en verdi som implementerer den for en bestemt URI. Instansen inneholder den konkrete map. Vi skriver Array-instansen i neste leksjon; her ser De formen på den.

declare const arrayFunctor: Functor<"Array">;
const out = arrayFunctor.map([1, 2, 3], n => n * 2); // number[]

Hvorfor dette er «lettvekt»

Det kalles mønsteret for lettvekts-HKT fordi det ikke trenger kompilatorendringer eller spesiell syntaks, bare grensesnitt og indeksert tilgang. Kostnaden er litt ekstra omstendelighet (URI-er og registre) i bytte mot ekte containergenerisk kode.

type Kind<F extends URIS, A> = URItoKind<A>[F];
// No magic, just a typed lookup table

Begrensninger

Mønsteret er omstendelig, og feilmeldinger kan være kryptiske fordi de omtaler kodingen i stedet for domenet Deres. Det krever også at hver container registreres. I de fleste apper bruker De biblioteker som allerede gjør dette, i stedet for å bygge det selv.

// Trade-off: real abstraction power vs. encoding ceremony

Sette alt sammen

Den fullstendige oppskriften på lettvekts-HKT er: definer en URI, registrer den i URItoKind, definer abstraksjoner med Kind<F, A>, og oppgi instanser per URI. Dette er hele verktøysettet bak generiske funksjonelle biblioteker i TypeScript.

type Kind<F extends URIS, A> = URItoKind<A>[F];
interface Functor<F extends URIS> {
  map<A, B>(fa: Kind<F, A>, f: (a: A) => B): Kind<F, B>;
}

Kort kontroll

Test forståelsen Deres av lettvekts-HKT-mønsteret.

Oppsummering

De har satt sammen lettvekts-HKT-mønsteret.

  • Defunksjonalisering erstatter anvendelse av typefunksjoner med et oppslag.
  • Kind<F, A> løser en URI og et argument til en konkret type.
  • Generiske signaturer bruker Kind i stedet for F<A>.
  • Det skalerer til to argumenter via Kind2 og følger fp-ts-konvensjonen.

Neste trinn er en generisk map med faktiske instanser.

Gratis å komme i gang

Lær deg TypeScript med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
101
Leksjoner
352

Ofte stilte spørsmål

Er leksjonen «Det lettvektsbaserte HKT-mønsteret» gratis?

Ja – hele teksten i «Det lettvektsbaserte HKT-mønsteret» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av TypeScript Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i TypeScript Academy inneholder totalt 4 leksjoner.

Hva lærer jeg i «Det lettvektsbaserte HKT-mønsteret»?

Implementer defunksjonaliseringsknepet Kind/URI. Du øver på TypeScript Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med TypeScript Academy?

Ingen tidligere erfaring er nødvendig. TypeScript Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Det lettvektsbaserte HKT-mønsteret»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne TypeScript Academy-leksjonen?

Ja. Alle TypeScript Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. HKT-problemet i TypeScript
  2. Definere typekonstruktører
  3. Det lettvektsbaserte HKT-mønsteret
  4. Generiske funktorer og mappere
← Tilbake til TypeScript Academy