In this carta da SPJ, a pagina 3 e 4, è scritto:La corrispondenza del modello sulle funzioni a livello di tipo è possibile, ma non sul livello di valore, perché questa differenza?
class Mutation m where
type Ref m :: * -> *
newRef :: a -> m (Ref m a)
readRef :: Ref m a -> m a
writeRef :: Ref m a -> a -> m()
instance Mutation IO where
type Ref IO = IORef
newRef = newIORef
readRef = readIORef
writeRef = writeIORef
instance Mutation (ST s) where
type Ref (ST s) = STRef s
newRef = newSTRef
readRef = readSTRef
writeRef = writeSTRef
e:
La dichiarazione della classe introduce ora una funzione di tipo Ref (con un tipo specificato ) a fianco le solite funzioni di valore come newRef (ognuna con un tipo specificato). Analogamente, ogni dichiarazione di istanza contribuisce con una clausola che definisce la funzione di tipo sul tipo di istanza insieme a un testimone per ogni funzione di valore.
Diciamo che Ref è una famiglia di tipo o un tipo associato della classe Mutation. Si comporta come una funzione al livello di tipo, quindi chiamiamo anche una funzione di tipo Ref. L'applicazione di una funzione di tipo utilizza la stessa sintassi dell'applicazione di un costruttore di tipo : Rif m a sopra significa applicare la funzione di tipo Rif a m, quindi applicare il costruttore di tipi risultante a a.
Quindi, in altre parole,
Ref :: (*->*)->*->*
cioè Ref
prende una funzione livello tipo come argomento, come Maybe
o IO
o []
e produce un'altra funzione livello di tipo, ad esempio IORef
usando una corrispondenza di modello , vale a dire Ref
è definito da una corrispondenza di modello .
Quindi, come è possibile che sia possibile associare la corrispondenza alle funzioni a livello di tipo ma non a livello di valore?
Ad esempio,
fun2int:: (Int->Int)->Int
fun2int (+)=2
fun2int (*)=3
non è possibile scrivere perché uguaglianza funzioni è undecidable.
1) Quindi, come è possibile che a livello di tipo questo non causi problemi?
2) È perché le funzioni a livello di tipo sono di tipo molto limitato? Quindi nessun tipo di funzione a livello di tipo può essere un argomento per Ref
, solo alcuni selezionati, vale a dire quelli dichiarati dal programmatore e non funzioni come (+), che sono più generali di quelli dichiarati dal programmatore? È questo il motivo per cui la corrispondenza del modello di funzione di livello del tipo non causa alcun problema?
3) La risposta a questa domanda è relativa alla parte this delle specifiche GHC?
Buona domanda. Il motivo principale è (2). Ad esempio, non è possibile passare una famiglia di tipi parzialmente applicata a un'altra famiglia di tipi, che sarebbe molto potente e creerebbe l'indecidibilità. È possibile eseguire la corrispondenza del modello solo sui costruttori di tipi, che non sono mai riducibili. – luqui
Grazie luqui, potresti spiegarlo più dettagliatamente? Non capisco cosa intendi per riduzione. – jhegedus
"Pattern matching" sui tipi funziona per unificazione - unificare due tipi è una procedura decidibile, i tipi vengono semplicemente confrontati strutturalmente e quindi nominalmente per decidere se sono uguali. Le funzioni a livello di valore, d'altra parte, non hanno una tale procedura per dedurre se sono uguali (eccetto il confronto di tutti gli input e gli output - che è troppo lento per essere persino vicino alla pratica). Se si dichiarano due tipi Forse identici, il compilatore insisterà che sono distinti (giustamente) ma nel mondo ipotetico con l'uguaglianza di funzione, questo sarebbe probabilmente un comportamento molto inaspettato. – user2407038