La restrizione valore fa riferimento nel avviso è una delle cose più complicato da capire in SML, ma farò del mio meglio per spiegare il motivo per cui si tratta in questo caso e cercare di puntare verso alcune risorse per imparare Di Più.
Come sapete, SML utilizzerà l'inferenza di tipo per dedurre la maggior parte dei tipi nei vostri programmi. In questo programma, il tipo di my_func
sarà dedotto per essere ('a -> 'b option) -> 'a list -> 'b
. Come hai notato, è un tipo polimorfico. Quando si chiama my_func
come questo
myfunc f [NONE, SOME 1, NONE];
... le variabili di tipo 'a
e 'b
sono istanziati per int option
e int
.
Tuttavia quando lo si chiama, senza un valore come SOME 1
sopra
myfunc f [NONE, NONE];
Cosa pensi delle variabili di tipo dovrebbero essere istanziati a? I tipi devono essere polimorfici, ad esempio 't option
e 't
per tutti i tipi 't
. Tuttavia, esiste una limitazione che impedisce a valori come questo di assumere tipi polimorfici.
SML definisce alcune espressioni come valori non espansivi e solo questi valori possono assumere tipi polimorfici.Essi sono:
- letterali (costanti)
- variabili
- funzione espressioni
- costruttori (ad eccezione di
ref
) applicato ai valori non espansive
- a valori non espansive con un tipo di annotazione
- tuple in cui ogni campo è un valore non espansivo
- record in cui ogni campo è un valore non espansivo
- liste in cui ogni campo è un valore non espansiva
tutte le altre espressioni, in particolare chiamate di funzione (che è ciò che la chiamata a my_func
è) non può essere polimorfico. Neanche i riferimenti. Si potrebbe essere curioso di vedere che quanto segue non solleva un avvertimento:
fn() => my_func f [NONE, NONE];
Invece, il tipo dedotto è unit -> 'a
. Se dovessi chiamare questa funzione, avresti di nuovo l'avviso.
La mia comprensione del motivo di questa restrizione è un po 'debole, ma credo che il problema di root sottostante sia un riferimento mutabile. Ecco un esempio che ho preso dal sito MLton link sottostante:
val r: 'a option ref = ref NONE
val r1: string option ref = r
val r2: int option ref = r
val() = r1 := SOME "foo"
val v: int = valOf (!r2)
Questo programma non TYPECHECK sotto SML, a causa della limitazione del valore. Se non fosse per la restrizione del valore, questo programma avrebbe un errore di tipo in fase di esecuzione.
Come ho detto, la mia comprensione è traballante. Tuttavia spero di aver gettato un po 'di luce sul problema che hai incontrato, anche se credo che nel tuo caso potresti tranquillamente ignorare l'avviso. Qui ci sono alcuni riferimenti dovrebbero decidere vuoi scavare più a fondo:
http://users.cis.fiu.edu/~smithg/cop4555/valrestr.html
http://mlton.org/ValueRestriction
(BTW il sito MLton è oro massiccio C'è così tanto nascosto qui, quindi se si. Stai cercando di capire qualcosa di strano su SML, ti consiglio vivamente di cercare qui perché probabilmente aumenterai molto di più di quanto inizialmente volevi)
Poiché sembra che tu stia effettivamente utilizzando SML/NJ, questo è un guida abbastanza utile per l'er messaggi ror e gli avvisi che vi darà al momento della compilazione:
http://flint.cs.yale.edu/cs421/smlnj/doc/errors.html
La ringrazio molto per la risposta informata! Analizzerò le risorse suggerite per ulteriori ricerche e riferirò se trovo un modo per risolvere questo messaggio di avviso. Come hai detto, potrebbe non essere possibile per quei determinati casi di test che sono vuoti o contengono semplicemente NONE, a causa della loro natura polimorfica. Grazie ancora per il vostro aiuto. – mbear
Nessun problema, felice di poterti aiutare.Un paio di cose che puoi fare per rimuovere l'avviso è (1) annotare con qualsiasi tipo, il che rende il valore non più polimorfico ovviamente: '(my_func f [NONE, NONE]): int' o (2) rendi conto solo di questo avviso si verifica quando si immette un valore come questo in REPL e probabilmente non verrà generato in un programma più grande che chiama 'my_func' con altri dati. – spacemanaki
Haskell ha una versione di questa stranezza, o la mancanza di riferimenti mutabili la sta salvando? –