Deci, există un astfel de programator pe Haskell. Aici managerul vine la el și spune, spunem, trebuie să învățăm cum să coacem pâinea. În general, nimic nu este clar, dar dacă este necesar, este necesar:
date Pâine = Pâine
Mai târziu, devine cunoscut faptul că pâinea, se pare, ar trebui să fie arsă în aragaz:
cuptor de date = Cuptor
date Pâine = Pâine
createBread. Cuptor -> Pâine
createBread _ = Pâine
După cum puteți vedea, acest lucru nu este suficient pentru moment. Pe lângă faptul că cuptoarele sunt de diferite tipuri:
cuptor de date = cabină electrică GasOven | MicrowaveOven
date Pâine = Pâine
createBread. Cuptor -> Pâine
createBread _ = Pâine
Prima condiție într-adevăr mai mult sau mai puțin interesantă este că cuptorul de gaz nu poate fi coace fără gaz:
date GasStatus = GasAvailable GasUnavailable
cuptor de date = cabină electrică GasOven | MicrowaveOven
date Pâine = Pâine
PâineCu se creează gaze de gaze disponibile = False
breadCouldBeCreated _ _ = Adevărat
createBread gaz atmosferă
| | pâineCu-ar fi creat gaz de cuptor = Doar pâine
| | altfel = nimic
Aici este introdus tipul de "stare de gaz". Gaz - fie este, fie nu este. Dacă folosim butelii de gaz, putem stoca cantitatea de gaz disponibil în litri, esența acestui lucru nu se schimbă. Funcția breadCouldBeCreated verifică dacă putem găti ceva în condițiile actuale (disponibilitatea gazului și tipul cuptorului).
Mai târziu, devine cunoscut faptul că, în plus față de pâinea din cuptor, puteți găti prăjituri și plăcinte cu diferite umpluturi:
date de umplutură = carne varză
date Alimentare = Cake | Pâine | Pastrare de umplutură
date GasStatus = GasAvailable GasUnavailable
cuptor de date = cabină electrică GasOven | MicrowaveOven
cuptorul de gaze cu gaze uzate este disponibil = fals
ovenCouldBeUsed _ _ = Adevărat
creați gaz de bucătărie alimentar
| | ovenCouldBeUsed gas oven = doar alimente
| | altfel = nimic
Introduceți tipurile de "produse alimentare" și "umplere". Funcția breadCouldBeCreated este redenumită în cuptorCouldBeUsed.
Managerul dorește ca prăjiturile, plăcintele și pâinea să fie coapte nu numai așa, ci în funcție de diferite rețete. Nu mai mult decât spus:
date de umplutură = carne varză
date Alimentare = Cake | Pâine | Pastrare de umplutură
date GasStatus = GasAvailable GasUnavailable
cuptor de date = cabină electrică GasOven | MicrowaveOven
cuptorul de gaze cu gaze uzate este disponibil = fals
ovenCouldBeUsed _ _ = Adevărat
creați gaz de bucătărie alimentar
| | ovenCouldBeUsed gas oven = doar alimente
| | altfel = nimic
breadRecipe = crea Paine
cakeRecipe = creați tort
pastyRecipe umplutură = creare $ Pasta de umplutură
Rețeta prescrie de obicei performanța unor acțiuni cu ingredientele, cuptorul și așa mai departe. Evident, rețeta este o funcție de ordin superior.
În cele din urmă, în cuptoare este necesar să ardeți cărămizi. Judecând după text, cărămizile ar trebui arse în aceleași cuptoare, inclusiv cuptorul cu microunde (deși în articolul despre Habr este introdusă o clasă separată a cuptorului):
date de umplutură = carne varză
date Alimentare = Cake | Pâine | Pastrare de umplutură
date GasStatus = GasAvailable GasUnavailable
cuptor de date = cabină electrică GasOven | MicrowaveOven
date Caramida = caramida
cuptorul de gaze cu gaze uzate este disponibil = fals
ovenCouldBeUsed _ _ = Adevărat
creați gaz de bucătărie alimentar
| | ovenCouldBeUsed gas oven = doar alimente
| | altfel = nimic
breadRecipe = crea Paine
cakeRecipe = creați tort
pastyRecipe umplutură = creare $ Pasta de umplutură
makeBrick gaz de cuptor
| | cuptorul gazului cuptorului este doar cărămidă
| | altfel = nimic
Aici tocmai am adăugat tipul de "cărămidă" și funcția "face o cărămidă".
Concluziile se sugerează. Obținem cod ușor de înțeles și ușor de urmărit. În procesul de scriere, construim cu ușurință și necontenit un model de domeniu, de fapt, pur și simplu făcând o traducere din limba rusă în Haskell. Fără moștenire, refactorizare sau UML.
Poate că, de fapt, se însemna că fiecare cuptor produce pâine și prăjituri puțin diferit și va trebui să introducem o clasă suplimentară de tipuri (sau, dacă doriți, o "interfață") cu instanțele corespunzătoare ale clasei. În același timp, nu trebuie să codificăm manual apelul cuptorului Utilizat oriunde se utilizează cuptorul. Dar nu pare că soluția va fi mult mai complicată din toate astea.
Și cum să coaceți pâinea?
Îți place postul? Trimiteți-le altora:
(JS trebuie să fie activată)