İlgili projelerin tavsiyelerine göre bilginizi geliştirerek ( nasıl ? ) paylaşabilirsiniz .
Bir cebirsel tür bir tür veri türü birleştirir işlevselliği kompozitin standart ürünler ( n küpe veya kayıtları) ve türleri ( ayrık birleşimi ). Özyineleme ile birlikte , listeler ve ağaçlar gibi yapılandırılmış verileri ifade etmenize olanak tanır.
Ürün tipi iki tür A ve B içindeki bir türü teorisi bir Kartezyen ürün koymak- ve gösterilir bir x B . Bu, birinci bileşeni A tipi ve ikinci tipi B olan çiftlerin tipidir . Her bileşenin değerini veren, projeksiyon adı verilen iki kurallı işlev onunla ilişkilendirilir .
Örnek: OCaml'de üretilen tür :Bir sözlük girişinin türü OCaml dilinde tanımlanabilir :
type dict_entry = string * int let entry = ("clé", 37) (* get_value : dict_entry -> int *) let get_value (key, value) = valueÜrün, doğal olarak, n tuple türlerini sağlamak için herhangi bir sayıda işlenene genelleştirilir . Boş ürün özel durumunda, 0-tuple tipine birim tipi denir ve 1 ile belirtilir : ürünün nötr öğesidir ve genellikle () olarak belirtilen tek bir değer içerir .
Pratik hususlar genellikle bileşenlerin isimlendirilmesine yol açar. Bu bağlamda tür genellikle yapı ve kayıtların değerleri olarak anılır ; bileşenlere üye denir ve üyeye göre izdüşüm mbir son ek notasyonu ile yazılır .m.
Örnek: OCaml'deki yapı:Yine OCaml'de, önceki örnek şu şekilde uyarlanır:
type dict_entry = { key : string ; value : int ; } let entry = { key = "clé" ; value = 37 } (* get_value : dict_entry -> int *) let get_value entry = entry.value Örnek: C dilinde yapı :Bu işlevsellik, (en) anahtar sözcüğüylestruct C diline çevrilmiştir :
typedef struct { char* key ; int value ; } dict_entry ; dict_entry entry = { .key = "clé", .value = 37 } ; int get_value (dict_entry entry) { return entry.value ; }Toplam tipi iki tip A ve B tipi teorik olarak benzer olan ayrık birleşimi ensemblist ve gösterilir bir + B . A ve B iki türünün her birinin tüm değerlerini içeren bir türü temsil eder , böylece A'dan gelen bir değer B'den gelen bir değerle karıştırılamaz ( A = B olsa bile ).
Küme teorisinde, toplamı {1} × A ∪ {2} × B ; böyle bir nesnenin birinci bileşeni (1 veya 2), bu nesnenin toplamın sol kolunda mı ( A ) yoksa sağ kolunda mı ( B ) olduğunu gösteren bir etikettir . (1, a ) ve (2, b ) ifadelerinin teorik analogları genellikle ι 1 a ve ι 2 b olarak gösterilir ( ι , Yunanca iota harfidir ). Bu gösterimler KORKULAR I 1 ve ι 2 olarak görülebilir injektif fonksiyonları sırasıyla, A bölgesindeki bir + B ve B de bir + b mümkün toplamı değerlerini oluşturmak için yapar, dolayısıyla kendi adına kurucular . Gelen ι 1 bir değer , bir adlandırılan bağımsız değişken yapıcısının ι 1 .
Bir toplam türündeki değerlerle uğraşmak, bu bağlamda model filtreleme olarak adlandırılan duruma göre akıl yürütmeyi gerektirir . Kurucusundan tanıdığımız ve bu kurucu injektif olduğu için değerini geri kazanabildiğimiz her kol ayrı bir davanın konusudur.
Örnek: OCaml'deki toplam türü:OCaml'de tam sayıların ve kayan noktalı sayıların ayrık birleşimini tanımlayabilir ve bu birleşim üzerinde bir işlevi filtreleyerek tanımlayabiliriz:
type sum = Int of int | Float of float (* print : sum -> unit *) let print = function | Int i -> Printf.printf "%i" i | Float f -> Printf.printf "%f" fBurada, yapıcılar adlandırılır Intve Float.
Örnek: C dilinde "birlik" yazın:Bu işlevsellik, bir etiket eklemeniz koşuluyla C dilinde (en) anahtar kelimesiyleunion yaklaşık olarak yapılır , ancak bu aynı garantileri sunmaz (toplam türündeki bir nesneyi etiketini yok sayarak okuyabilir ve değiştirebilirsiniz. hatalara neden olmak anlamına gelir ):
typedef struct { enum { INT, FLOAT } tag ; union { int i ; float f ; } ; } sum_t ; void print (sum_t x) { if (x.tag == INT) printf("%i", x.i) ; else if (x.tag == FLOAT) printf("%f", x.f) ; }Toplam, doğal olarak herhangi bir sayıda işlenene genellenir. Boş toplam özel durumunda , tür boş tür olarak adlandırılır ve 0 olarak not edilir : toplamın nötr öğesidir (ve ürünün soğurucu öğesidir ) ve hiçbir değer içermez.
Bir numaralandırılmış türü olan elemanlar, farklı kurucular sınırlı bir kümesini temsil etmektedir. Üzerinde bir fonksiyon tanımlamak, her bir elemanın görüntüsünü ayrı ayrı tanımlamak gibidir.
Örnek: OCaml'de numaralandırılmış tür:Örneğin, klasik bir kart oyununun dört rengini de kodlayabiliriz :
type couleur = Coeur | Carreau | Trefle | Pique (* nom_de_la_couleur : couleur -> string *) let nom_de_la_couleur = function | Coeur -> "♥ cœur" | Carreau -> "♦ carreau" | Trefle -> "♣ trèfle" | Pique -> "♠ pique" Örnek: C dilinde numaralandırılmış tür:Bu işlevsellik C diline şu anahtar sözcükle çevrilmiştir enum :
typedef enum { COEUR, CARREAU, TREFLE, PIQUE } couleur ; char* nom_de_la_couleur (couleur c) { switch (c) { case COEUR : return "♥ cœur" ; case CARREAU : return "♦ carreau" ; case TREFLE : return "♣ trèfle" ; case PIQUE : return "♠ pique" ; } }Bir cebirsel tip bir ürün toplamıdır ve bu nedenle bu iki kavramları genelleştirilmiş.
Bu nedenle, cebirsel türlerin özel durumları, ürün türleri (tek bir kurucu), toplam türleri (her kurucu için tek bir argüman) ve numaralandırma türleridir (argümansız birkaç kurucu).
Örnek: seçenek türü ve sonuç türü:Türü seçeneklerini (in) cebirsel tip ortak uygulamalardır. Belirli bir türe, “tanımsız” olarak kabul edilen veya bir hata değeri ( nullbazı programlama dillerinde eşdeğeri ) olarak kabul edilen, kısmi işlevlerin kontrollü bir şekilde tanımlanmasına izin veren özel bir değerin eklenmesine izin verirler .
Özel değer, Nonehiçbir argüman almayan bir kurucu tarafından temsil edilirken, tamamlanacak türün değerleri bir kurucuya sarılır Some(bu nedenle bu türden bir argüman alır).
type int_option = None | Some of int (* division : int -> int -> int_option *) let division x y = if y = 0 then None else Some (x / y)Mekanizma, hata durumunu bir açıklama mesajıyla (veri türü string) geliştirerek geliştirilebilir.
type int_result = Result of int | Error of string (* division : int -> int -> int_result *) let division x y = if y = 0 then Error "division by zero" else Result (x / y)Gelen dillere onlara destek, cebirsel türleri olabilir (parametrik) polimorfik verir, jenerik programlama . Böylece, bir cebirsel türün tanımı, tür değişkenleri tarafından parametrelenebilir.
Daha sonra bu tür polimorfik tipler üzerinde etkili olan genel fonksiyonları tanımlayabiliriz.
Örnek: polimorfik seçenek türü:Daha önce görülen opsiyon tipinin tanımı polimorfik hale getirilebilir. OCaml dilinde aşağıdaki gibi yazılmıştır (burada 'abir tür değişkenini belirtir):
type 'a option = None | Some of 'a (** Utilisation d’instances du type polymorphe : **) (* int_division : int -> int -> int option *) let int_division x y = if y = 0 then None else Some (x / y) (* float_division : float -> float -> float option *) let float_division x y = if y = 0.0 then None else Some (x /. y) (** Définition d’une fonction générique : **) (* get_value : 'a -> 'a option -> 'a *) let get_value default_value optional_value = match optional_value with | None -> default_value | Some value -> valueCebirsel türün en önemli örneklerinden biri , iki kurucu tarafından özyinelemeli olarak tanımlanan liste türüdür :
Örneğin, Eksiler 1 (Eksiler 2 (Eksiler 3 (Eksiler 4 Nil))) , ayrıca not edilir 1 :: 2 :: 3 :: 4 :: [], bu sırayla dört öğe 1, 2, 3, 4'ten oluşan listedir.
Tüm liste işlemleri daha sonra model filtreleme kullanılarak yineleme ile tanımlanır. Örneğin, bir listenin uzunluğunu hesaplamak için:
Bu tanım böylece OCaml diline çevrilir:
type 'a list = | Nil | Cons of 'a * 'a list let list1234 = Cons 1 (Cons 2 (Cons 3 (Cons 4 Nil))) let rec length = function | Nil -> 0 | Cons x s -> 1 + length sCebirsel türler, ağaç yapılarını tanımlamanıza da olanak tanır . İki kurucu kullanılarak bir ikili ağaç oluşturulabilir:
Örneğin,
Node 1 (Node 2 (Leaf 4) (Node 5 (Leaf 6) (Leaf 7) ) ) (Leaf 3)aşağıdaki ağaçtır:
1 / \ 2 3 / \ 4 5 / \ 6 7Listelere gelince, ağaçlar üzerindeki işlemler tümevarımla tanımlanır. Örneğin, bir ağacın yüksekliğini hesaplamak için:
Bu tanım böylece OCaml diline çevrilir:
type tree = | Leaf of int | Node of tree * int * tree let my_tree = Node 1 (Node 2 (Leaf 4) (Node 5 (Leaf 6) (Leaf 7))) (Leaf 3) let rec height = function | Leaf e -> 1 | Node e l r -> 1 + max (height l) (height r)Cebirsel bir tür soyut olabilir : bunun için iç yapısını (kurucularını ve çeşitli alanlarını) ortaya çıkarmamak yeterlidir. Böylece sadece bu amaç için sağlanan işlevler tarafından ele alınabilir ve uygulaması değiştirilebilir.
Cebirsel türleri karmaşık veri yapılarını gerçekleştirmeye izin verdiği için sık kullanılan bir tekniktir.