C'è un post di blog da qualche parte con un'implementazione di livello tipo del calcolo del combinatore SKI, che è noto per essere completato da Turing.
I sistemi di tipo Turing-completi hanno sostanzialmente gli stessi vantaggi e gli stessi inconvenienti dei linguaggi completi di Turing: puoi fare qualsiasi cosa, ma puoi dimostrarti molto poco. In particolare, non puoi provare che alla fine farai qualcosa.
Un esempio di calcolo a livello di carattere sono i nuovi trasformatori di raccolta preservazione di tipo in Scala 2.8. In Scala 2.8, metodi come map
, filter
e così via sono garantiti per restituire una collezione dello stesso tipo su cui sono stati chiamati. Quindi, se si filter
a Set[Int]
, si ottiene un Set[Int]
e se si map
a List[String]
si ottiene un List[Whatever the return type of the anonymous function is]
.
Ora, come potete vedere, map
può effettivamente trasformare il tipo di elemento. Quindi, cosa succede se il nuovo tipo di elemento non può essere rappresentato con il tipo di raccolta originale? Esempio: a BitSet
può contenere solo numeri interi a larghezza fissa. Quindi, cosa succede se si dispone di un BitSet[Short]
e si mappa ogni numero con la sua rappresentazione di stringa?
someBitSet map { _.toString() }
Il risultato sarebbe essere un BitSet[String]
, ma questo è impossibile. Quindi, Scala sceglie il supertipo più derivato di BitSet
, che può contenere un String
, che in questo caso è un Set[String]
.
Tutto questo calcolo è in corso durante di compilazione, o più precisamente durante tipo tempo controllo, utilizzando le funzioni di tipo-livello. Pertanto, è staticamente garantito che sia sicuro per il tipo, anche se i tipi sono effettivamente calcolati e quindi non noti in fase di progettazione.
fonte
2010-10-28 22:44:22
Preferirei avere un sistema di tipo non universale e un compilatore veloce. – ziggystar
@ziggystar cosa si otterrebbe con la velocità di compilazione che probabilmente si perderebbe in tempo di sviluppo e di debug. – BAR