2015-09-16 14 views
6

Mi è appena venuto in mente che i generici di F # non sembrano accettare valori costanti come "parametri modello".Nessun F # generico con "argomenti modello" costanti?

Supponiamo di voler creare un tipo RangedInt tale che si comporti come un int ma è garantito che contenga solo un sottointervallo di valori interi.

Un possibile approccio potrebbe essere un'unione discriminata, simile a:

type RangedInt = | Valid of int | Invalid 

Ma questo non funziona neanche, in quanto non v'è alcuna "memoria specifica il tipo di informazioni range". E 2 istanze RangedInt dovrebbero essere di tipo diverso, anche se l'intervallo è diverso.

Essere ancora un po 'C++ infestata sarebbe simile a:

template<int low,int high> 
class RangedInteger { ... }; 

Ora la domanda, derivante è duplice:

  1. Mi sono perso qualcosa e valori costanti per F # generics esiste?
  2. Se non mi mancasse quello, quale sarebbe il modo idiomatico per realizzare un tale RangedInt<int,int> in F #?

Dopo aver trovato Tomas Petricek's blog about custom numeric types, l'equivalente alla mia domanda per questo articolo del blog sarebbe: E se non ha fatto un, ma un tipo di famiglia IntegerZn<int> personalizzato IntegerZ5?

risposta

7

La funzione della lingua richiesta è denominata Dependent Types e F # non dispone di tale funzionalità.

Non è una funzionalità di linguaggio particolarmente comune, e persino Haskell (che la maggior parte degli altri linguaggi di programmazione Functional 'guarda fino a') in realtà non ce l'ha.

sono lingue con tipi dipendenti là fuori, ma nessuno di loro considererei mainstream. Probabilmente quello che sento di più è Idris.

+0

In effetti, ho passato un po 'di tempo ieri su tipi dipendenti e ho trovato una mutazione ML chiamata ATS (non riuscivo a farlo funzionare, però). L'idea è di avere un linguaggio che combini programmazione logica e solutori in fase di compilazione in modo che le persone possano scrivere prove per il loro codice - quelli che vengono rimossi in fase di compilazione dopo aver verificato il codice con esso. La mia idea di F # era fondamentalmente: quanto lontano posso andare in quella direzione usando un linguaggio mainstream moderno? – BitTickler

1

Mi sono perso qualcosa e i valori costanti per i generici F # esistono?

Mentre F # ha inferenza di tipo molto forte rispetto ad altri linguaggi .NET, nel suo cuore è costruito su .NET.

E i generici .NET supportano solo un piccolo sottoinsieme di ciò che è possibile con i modelli C++. Tutti gli argomenti tipo per i tipi generici devono essere tipi e non esiste nemmeno l'impostazione predefinita degli argomenti tipo.

Se non mi mancasse quello, quale sarebbe il modo idiomatico per realizzare un tale RangedInt in F #?

Dipenderebbe dai dettagli. Impostare i limiti in fase di esecuzione è una possibilità - questo sarebbe il solito approccio in .NET. Un altro sarebbe unità di misura (questo sembra meno probabile che sia un adattamento).

E se non fosse un IntegerZ5 ma una famiglia di tipo personalizzato IntegerZn<int>?

Vedo due motivi:

  • Si tratta di un esempio, ed evitando generici mantiene le cose più semplici concentrarsi permettendo sul punto dell'esempio.
  • Quale altro tipo di sottostruttura si userebbe comunque? Sui sistemi moderni di tipo più piccolo (byte, Int16 ecc.) sono meno efficienti (a meno che lo spazio in fase di esecuzione non sia una preoccupazione travolgente); long aggiungerebbe dimensioni senza benefici (si manterranno solo 5 valori possibili).
+0

Sì, e tenere lontano dai farmaci generici ha anche tenuto l'articolo lontano dal problema nella mia domanda :) In altre parole, il '' IntegerZn '' era inteso nel senso di '' IntegerZn <5> '', non nel "quale tipo di base usare" tipo di senso. – BitTickler

+0

E l'impostazione dei valori in fase di runtime non è un'opzione, in quanto ciò che cerco di ottenere è che il sistema di tipi cattura gli errori in fase di compilazione. Se era di tipo 1 con le impostazioni di intervallo, sarebbe ancora ma 1 tipo. – BitTickler

Problemi correlati