Accettabile tipi Numerici.ANNUNCIO funzioni
-
11-12-2019 - |
Domanda
Sto avendo poco successo avvolgere la mia testa intorno all'impianto idraulico di base dei tipi coinvolti nella ad
pacchetto.Per esempio, il seguente funziona perfettamente:
import Numeric.AD
ex :: Num a => [a] -> a
ex [x, y] = x + 2*y
> grad ex [1.0, 1.0]
[1.0, 2.0]
dove grad
è del tipo:
grad
:: (Num a, Traversable f) =>
(forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
-> f a -> f a
Se cambio il tipo di firma di ex
per [Double] -> Double
e provare a fare la stessa cosa, ho
Couldn't match expected type `AD s a0' with actual type `Double'
Expected type: f0 (AD s a0) -> AD s a0
Actual type: [Double] -> Double
Lo stesso comportamento si verifica quando si sostituisce Double
con apparentemente alcun tipo di costruttore di tipo *
che crea Num
.
Quando il Traversable f
è un elenco, il primo argomento di grad
deve avere tipo [AD s a] -> AD s a
per alcuni accettabile Mode
- ad esempio, Reverse
.Ma chiaramente l'utente di grad
non hanno a che fare con il AD
il costruttore o il Mode
direttamente.Sbirciare in questi interni mi hanno lasciato un po ' confuso;in particolare, non riesco a seguire il tipo di/il tipo di sentiero per la differenza tra l'utilizzo di Num a => [a] -> a
e [Double] -> Double
.
Perché il tipo di firma [Double] -> Double
causa problemi con grad
?E in termini di pianura, di antica biblioteca, utilizzare:c'è un modo per utilizzare il [Double] -> Double
la versione di ex
, o è un polimorfici versione necessarie?
(titolo ispirato da questa domanda simile)
Soluzione
Non so il ad
biblioteca, ma dal momento che grad
si aspetta una funzione del tipo [AD s a] -> AD s a
come primo parametro, non ci si può aspettare di essere in grado di passare una funzione del tipo [Double] -> Double
, poiché Double
e AD
sono tipi completamente diversi.
Una generica funzione con Num
vincolo di opere, perché AD
di per sé è anche un'istanza di Num
, quindi nel tuo esempio, ex
ottiene specializzato per qualcosa di simile
ex :: (Mode s, Fractional a) => [AD s a] -> AD s a
Se si desidera specializzarsi ex
per i calcoli utilizzando Raddoppia, è necessario dare una firma come
ex :: Mode s => [AD s Double] -> AD s Double