EDIT
Meglio/recente Info è qui: Keeping partially applied function generic
(originale sotto)
penso una cosa pragmatica qui non è cercare di capire questo troppo profondamente, ma piuttosto conoscere un paio di strategie generali per superare la VR e andare avanti con il tuo lavoro. È una risposta un po 'fuoriuscita, ma non sono sicuro che abbia senso dedicare del tempo a comprendere le intrecci del sistema di tipo F # (che continua a cambiare in modi minori da versione a versione) qui.
Le due strategie principali che vorrei sostenere sono queste. In primo luogo, se si sta definendo un valore con un tipo di funzione (tipo con una freccia '->'), quindi assicurarsi che sia una funzione sintattica facendo eta-conversion:
// function that looks like a value, problem
let tupleList = List.map (fun x -> x,x)
// make it a syntactic function by adding argument to both sides
let tupleList l = List.map (fun x -> x,x) l
In secondo luogo, se si incontrano ancora VR/generalizzando problemi, quindi specificare l'intero firma tipo di dire ciò che si vuole (e poi 'marcia indietro', come F # permette):
// below has a problem...
let toleq (e:float<_>) a b = (abs (a - b)) < e
// so be fully explicit, get it working...
let toleq<[<Measure>]'u> (e:float<'u>) (a:float<'u>) (b:float<'u>) : bool =
(abs (a - b)) < e
// then can experiment with removing annotations one-by-one...
let toleq<[<Measure>]'u> e (a:float<'u>) b = (abs (a - b)) < e
Penso che queste due strategie sono il miglior consiglio pragmatico. Detto questo, ecco il mio tentativo di rispondere alle tue domande specifiche.
Non so.
'>' è una funzione completamente generica ('a ->' a -> bool) che funziona per tutti i tipi, e quindi is_bigger generalizza. D'altra parte, '+' è una funzione 'in linea' che funziona su una manciata di tipi primitivi e una certa classe di altri tipi; può essere generalizzato solo all'interno di altre funzioni 'inline', altrimenti deve essere bloccato a un tipo specifico (o verrà impostato su 'int'). (Il metodo "in linea" del polimorfismo ad-hoc è il modo in cui gli operatori matematici in F # superano la mancanza di "classi di tipi".)
Questo è il problema della "funzione sintattica" di cui sopra; 'compiliamo in campi/proprietà che, a differenza delle funzioni, non possono essere generici. Quindi, se vuoi che sia generico, rendilo una funzione. (Vedi anche this question per un'altra eccezione a questa regola.)
Croce rif ad un'altra domanda su stesso argomento: http://stackoverflow.com/questions/416508/f-compiler-error-fs0030-problems-with-the-value-restriction – Benjol