Tipi come cittadino di prima classe


10

Proveniente da un background C ++ Non capisco perché uno ha bisogno di tipi / espressioni di tipo come cittadino di prima classe? L'unica lingua che conosco che supporta questa funzione è Aldor.

Qualcuno ha qualche letteratura sui tipi come cittadino di prima classe o conosce alcuni motivi per cui è utile?


3
Anche Idris ha questi.
ThreeFx,

1
Ti stai chiedendo il concetto generale di "tipo è un valore" (chiamato "riflessione" o "metaclassi" in varie lingue) o del concetto più specifico di espressioni di tipo?
svick,

1
@svick Sono interessato a quest'ultimo. Sfortunatamente non ho trovato molte cose generali sulle espressioni di tipo, quindi sarebbe bello se potessi suggerire un po 'di letteratura.
paul98

Risposte:


11

I tipi di prima classe abilitano qualcosa chiamato digitazione dipendente . Ciò consente al programmatore di utilizzare valori di tipi a livello di tipo. Ad esempio, il tipo di tutte le coppie di numeri interi è un tipo normale, mentre la coppia di tutti i numeri interi con il numero sinistro più piccolo del numero destro è un tipo dipendente. L'esempio introduttivo standard di questo è elenchi codificati in lunghezza (generalmente chiamati Vectorin Haskell / Idris). Il seguente pseudo-codice è una miscela di Idris e Haskell.

-- 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

Questo pezzo di codice ci dice due cose:

  • L'elenco vuoto ha lunghezza zero.
  • consl'inserimento di un elemento in un elenco crea un elenco di lunghezza n + 1

Sembra molto simile a un altro concetto con 0 e n + 1non è vero? Tornerò su quello.

Cosa ci guadagna da questo? Ora possiamo determinare proprietà aggiuntive delle funzioni che utilizziamo. Ad esempio: una proprietà importante di appendè che la lunghezza dell'elenco risultante è la somma delle lunghezze dei due elenchi di argomenti:

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

Ma tutto sommato questa tecnica non sembra tutto utile nella programmazione quotidiana. In che modo ciò si riferisce a socket, POST/ GETrichieste e così via?

Beh, non lo fa (almeno non senza un notevole sforzo). Ma può aiutarci in altri modi:

I tipi dipendenti ci consentono di formulare invarianti nel codice - regole come il comportamento di una funzione. Usando questi abbiamo ulteriore sicurezza sul comportamento del codice, simile alle pre e post-condizioni di Eiffel. Ciò è estremamente utile per la dimostrazione di teoremi automatizzati, che è uno dei possibili usi di Idris.

Tornando all'esempio sopra, la definizione di elenchi codificati in lunghezza ricorda il concetto matematico di induzione . In Idris, puoi effettivamente formulare il concetto di induzione su un elenco come il seguente:

              -- 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

Questa tecnica è limitata a prove costruttive, ma è comunque molto potente. Puoi provare a scrivere appendinduttivamente come esercizio.

Naturalmente, i tipi dipendenti sono solo un uso dei tipi di prima classe, ma è probabilmente uno dei più comuni. Ulteriori usi includono, ad esempio, la restituzione di un tipo specifico da una funzione basata sui suoi argomenti.

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

Questo è un esempio senza senso, ma dimostra qualcosa che non puoi emulare senza tipi di prima classe.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.