This shows you the differences between two versions of the page.
pp:24:laboratoare:haskell:tipuri [2024/04/10 19:52] florin.mihalache created |
pp:24:laboratoare:haskell:tipuri [2024/04/20 22:09] (current) florin.mihalache |
||
---|---|---|---|
Line 2: | Line 2: | ||
* Data publicării: 10.04.2024 | * Data publicării: 10.04.2024 | ||
- | * Data ultimei modificări: 10.04.2024 | + | * Data ultimei modificări: 20.04.2024 |
===== Obiective ===== | ===== Obiective ===== | ||
Line 227: | Line 227: | ||
maybeHead (x : _) = Just x | maybeHead (x : _) = Just x | ||
maybeHead _ = Nothing | maybeHead _ = Nothing | ||
+ | |||
+ | </code> | ||
+ | **Observație**: Parametrizarea la nivel de tip poate fi efectuată și în cazul construcțiilor ''%%type%%'' și ''%%newtype%%'' (prezentată mai jos), în mod similar cu ''%%data%%''. | ||
+ | |||
+ | ==== Tipuri recursive ==== | ||
+ | |||
+ | Haskell permite **recurența** la nivel de tip, mai exact referirea tipului declarat la un moment dat în cadrul propriilor constructori. Astfel, putem defini tipul listă în următorul fel: | ||
+ | |||
+ | <code> | ||
+ | data List a = Void | Cons a (List a) deriving Show | ||
+ | |||
+ | </code> | ||
+ | Această construcție este de fapt implicit prezentă în Haskell, ca **zahăr sintactic**: | ||
+ | |||
+ | <code> | ||
+ | data [a] = [] | a : [a] deriving Show | ||
+ | |||
+ | </code> | ||
+ | Un alt exemplu este definirea mulțimii numerelor naturale în aritmetica Peano: | ||
+ | |||
+ | <code> | ||
+ | data Natural = Zero | Succ Natural deriving Show | ||
+ | |||
+ | </code> | ||
+ | ===== newtype ===== | ||
+ | |||
+ | Construcția ''%%newtype%%'' este similară cu ''%%data%%'', cu diferența că ne permite crearea unui tip de date cu **un singur** constructor și **cu un singur** câmp, pe baza altor tipuri de date existente. De exemplu: | ||
+ | |||
+ | <code> | ||
+ | newtype Celsius = MakeCelsius Float deriving Show | ||
+ | |||
+ | </code> | ||
+ | sau | ||
+ | |||
+ | <code> | ||
+ | newtype Celsius = MakeCelsius { getDegrees :: Float } deriving Show | ||
+ | |||
+ | </code> | ||
+ | folosind sintaxa de tip înregistrare. | ||
+ | |||
+ | Observăm că ''%%newtype%%'', spre deosebire de ''%%type%%'', creează un **nou tip**, nu un tip identic. Acest lucru ne este util când dorim să forțăm folosirea unui anumit tip cu o semantică dată. De exemplu atât ''%%Celsius%%'' cât și ''%%Fahrenheit%%'' pot fi reprezentate ca ''%%Float%%'', însă acestea sunt tipuri de date diferite: | ||
+ | |||
+ | <code> | ||
+ | newtype Fahrenheit = MakeFahrenheit Float deriving Show | ||
+ | |||
+ | celsiusToFahrenheit :: Celsius -> Fahrenheit | ||
+ | celsiusToFahrenheit (MakeCelsius c) = MakeFahrenheit $ c * 9/5 + 32 | ||
+ | |||
+ | </code> | ||
+ | Diferența principală între ''%%data%%'' și ''%%newtype%%'' este că ''%%newtype%%'' permite crearea de tipuri **izomorfe**: atât ''%%Celsius%%'' cât și ''%%Fahrenheit%%'' sunt tipuri identice cu ''%%Float%%'' din punctul de vedere al structurii, însă folosirea lor în cadrul programului diferă, ''%%Float%%'' având o semantică mai generală (orice număr în virgulă mobilă). | ||
+ | |||
+ | ===== Resurse ===== | ||
+ | |||
+ | * [[https://github.com/cs-pub-ro/PP-laboratoare/raw/master/haskell/tipuri/haskell-cheatsheet-2.pdf|Cheatsheet]] | ||
+ | * [[https://ocw.cs.pub.ro/courses/_media/pp/24/laboratoare/haskell/tipuri-schelet.zip|Schelet]] | ||
+ | * [[https://ocw.cs.pub.ro/courses/_media/pp/24/laboratoare/haskell/tipuri-solutii.zip|Soluții]] | ||
+ | |||
+ | ===== Referințe ===== | ||
+ | |||
+ | * //[[http://www.haskell.org/haskellwiki/Algebraic_data_type|Algebraic data type]]// | ||
+ | * //[[http://en.wikibooks.org/wiki/Haskell/Type_declarations|Haskell Wikibook]]// - Declararea tipurilor | ||
+ | * //[[https://wiki.haskell.org/Constructor|Constructor]]// - Distincție între constructori de tip și constructori de date | ||
+ | * //[[http://learnyouahaskell.com/making-our-own-types-and-typeclasses|Learn you a Haskell]]// - Capitolul "Making your own types" | ||
+ | * //[[https://book.realworldhaskell.org/read/defining-types-streamlining-functions.html|Real World Haskell]]// - Capitolul "Defining types" | ||
+ | |||