Birinci sınıf tipleri, bağımlı yazma adı verilen bir şeyi etkinleştirir . Bunlar, programlayıcının tür düzeyinde tür değerlerini kullanmasına izin verir. Örneğin, tam sayı çiftlerinin türü normal bir türken, sol sayı doğru sayıdan küçük olan tüm tam sayıların çifti bağımlı bir türdür. Bunun standart giriş örneği uzunluk kodlu listelerdir (genellikle Vector
Haskell / Idris olarak adlandırılır ). Aşağıdaki sözde kod, Idris ve Haskell'in bir karışımıdır.
-- a natural number
data Nat = Zero | Successor Nat
data Vector length typ where
Empty : Vector Zero typ
(::) : typ -> Vector length typ -> Vector (Successor length) typ
Bu kod parçası bize iki şey söyler:
- Boş listenin uzunluğu sıfırdır.
cons
bir öğeyi listeye eklemek uzunluk listesi oluşturur n + 1
Bu, 0 ile başka bir konsepte çok benziyor ve n + 1
değil mi? Ben buna geri döneceğim.
Bundan ne kazanıyoruz? Artık kullandığımız fonksiyonların ek özelliklerini belirleyebiliriz. Örneğin: append
öğesinin önemli bir özelliği , sonuç listesinin uzunluğunun, iki bağımsız değişken listesinin uzunluklarının toplamı olmasıdır:
plus : Nat -> Nat -> Nat
plus Zero n = n
plus (Successor m) n = Successor (plus m n)
append : Vector n a -> Vector m a -> Vector (plus n m) a
append Empty ys = ys
append (x::xs) ys = x :: append xs ys
Ama tüm bu teknikte günlük programlamada yararlı görünmüyor. Bu soketler, POST
/ GET
istekler vb. İle nasıl ilişkilidir ?
İyi değil (en azından kayda değer çaba sarf etmeden). Ancak bize başka şekillerde de yardımcı olabilir:
Bağımlı tipler, kod kurallarında değişmezleri formüle etmemize izin verir. Bunları kullanarak, Eiffel'in ön ve son koşullarına benzer şekilde kodun davranışı hakkında ek güvenlik elde ederiz. Bu, Idris'in olası kullanımlarından biri olan otomatik teorem kanıtlama için son derece yararlıdır.
Yukarıdaki örneğe dönersek, uzunluk kodlu listelerin tanımı, tümevarımın matematiksel kavramına benzemektedir . Idris'de, aslında böyle bir listede indüksiyon kavramını aşağıdaki gibi formüle edebilirsiniz:
-- If you can supply the following:
list_induction : (Property : Vector len typ -> Type) -> -- a property to show
(Property Empty) -> -- the base case
((w : a) -> (v : Vector n a) ->
Property v -> Property (w :: v)) -> -- the inductive step
(u : Vector m b) -> -- an arbitrary vector
Property u -- the property holds for all vectors
Bu teknik yapıcı kanıtlarla sınırlıdır, ancak yine de çok güçlüdür. append
Bir egzersiz olarak tümevarımsal olarak yazmaya çalışabilirsiniz .
Tabii ki, bağımlı türler birinci sınıf türlerinin sadece bir kullanımıdır, ancak tartışmasız en yaygın olanlardan biridir. Ek kullanımlar, örneğin, bağımsız değişkenlere dayalı bir işlevden belirli bir türün döndürülmesini içerir.
type_func : Vector n a -> Type
type_func Empty = Nat
type_func v = Vector (Successor Zero) Nat
f : (v : Vector n a) -> type_func v
f Empty = 0
f vs = length vs :: Empty
Bu saçma bir örnektir, ancak birinci sınıf türleri olmadan taklit edemediğiniz bir şeyi gösterir.