Permettetemi di rimediare a iniziare un po 'di questa confusione accendendo con un po' di ambiguità. Mi piace usare l'analogia con il livello di valore per spiegarlo, poiché le persone tendono ad avere più familiarità con esso.
Un costruttore di tipi è un tipo che è possibile applicare agli argomenti di tipo per "costruire" un tipo.
Un costruttore di valori è un valore che è possibile applicare agli argomenti valore per "costruire" un valore.
I costruttori di valori sono generalmente chiamati "funzioni" o "metodi". Si dice anche che questi "costruttori" siano "polimorfici" (perché possono essere usati per costruire "cose" di "forma" variabile), o "astrazioni" (poiché si astraggono su ciò che varia tra le diverse istanze polimorfiche).
Nel contesto dell'astrazione / polimorfismo, il primo ordine si riferisce al "monouso" dell'astrazione: astratti su un tipo una volta, ma quel tipo stesso non può astrarre su nulla. I generici Java 5 sono di primo ordine.
L'interpretazione di primo ordine delle suddette caratterizzazioni di astrazioni sono:
Un costruttore di tipi è un tipo che è possibile applicare agli argomenti di tipo corretto per "costruire" un tipo corretto.
Un costruttore di valori è un valore che è possibile applicare agli argomenti del valore corretto per "costruire" un valore corretto.
Per sottolineare che non vi è alcuna astrazione (suppongo che potresti chiamarlo "ordine zero", ma non l'ho visto usato da nessuna parte), come il valore 1
o il tipo String
, di solito diciamo che qualcosa è un valore o tipo "corretto".
Un valore corretto è "immediatamente utilizzabile", nel senso che non è in attesa di argomenti (non si basa su di essi). Pensali come valori che puoi facilmente stampare / ispezionare (serializzare una funzione è barare!).
Un tipo corretto è un tipo che classifica i valori (compresi i costruttori di valori), i costruttori di tipi non classificano alcun valore (devono prima essere applicati agli argomenti di tipo giusto per produrre un tipo corretto). Per creare un'istanza di un tipo, è necessario (ma non sufficiente) che sia un tipo corretto. (Potrebbe essere una classe astratta o una classe a cui non hai accesso.)
"Ordine superiore" è semplicemente un termine generico che significa un uso ripetuto di polimorfismo / astrazione. Significa la stessa cosa per tipi e valori polimorfici. Concretamente, un'astrazione di ordine superiore si sottrae a qualcosa che si sottrae a qualcosa. Per i tipi, il termine "di tipo superiore" è una versione speciale del più generale "ordine superiore".
Pertanto, la versione di ordine superiore della nostra caratterizzazione diventa:
Un costruttore di tipi è un tipo che è possibile applicare agli argomenti di tipo (tipi propri o costruttori di tipi) per "costruire" un tipo corretto (costruttore).
Un costruttore di valori è un valore che è possibile applicare agli argomenti valore (valori propri o costruttori di valori) per "costruire" un valore corretto (costruttore).
Quindi, "ordine superiore" significa semplicemente che quando dici "astrarre su X", lo intendi davvero! Ciò X
che viene sottratto non perde i suoi "diritti di astrazione": può astrarre tutto ciò che vuole. (A proposito, qui uso il verbo "abstract" per indicare: tralasciare qualcosa che non è essenziale per la definizione di un valore o tipo, in modo che possa essere variata / fornita dall'utente dell'astrazione come argomento .)
Ecco alcuni esempi (ispirati alle domande di Lutz via e-mail) di valori e tipi propri, di primo ordine e di ordine superiore:
proper first-order higher-order
values 10 (x: Int) => x (f: (Int => Int)) => f(10)
types (classes) String List Functor
types String ({type λ[x] = x})#λ ({type λ[F[x]] = F[String]})#λ
Dove le classi utilizzate sono state definite come:
class String
class List[T]
class Functor[F[_]]
Per evitare l'indirizzamento indiretto attraverso la definizione delle classi, è necessario in qualche modo esprimere funzioni di tipo anonimo, che non sono espresse direttamente in Scala, ma è possibile utilizzare tipi strutturali senza troppe spese generali sintattiche (lo #λ
stile è dovuto a https://stackoverflow.com / users / 160378 / retronym afaik ):
In alcune ipotetiche versioni future di Scala che supportano funzioni di tipo anonimo, è possibile abbreviare quest'ultima riga dagli esempi a:
types (informally) String [x] => x [F[x]] => F[String]) // I repeat, this is not valid Scala, and might never be
(A titolo personale, mi dispiace di aver mai parlato di "tipi di tipo superiore", dopo tutto sono solo tipi! Quando hai assolutamente bisogno di chiarire le idee, ti suggerisco di dire cose come "parametro parametro tipo", "membro tipo costruttore" , o "alias di tipo costruttore", per sottolineare che non stai parlando solo di tipi corretti.)
ps: A complicare ulteriormente le cose, "polimorfico" è ambiguo in un modo diverso, dal momento che un tipo polimorfico a volte significa un tipo quantificato universalmente, come ad esempio Forall T, T => T
un tipo appropriato, poiché classifica i valori polimorfici (in Scala, questo valore può essere scritto come tipo strutturale {def apply[T](x: T): T = x}
)