Sto riscuotendo un piccolo successo intorno alla tubatura di base dei tipi coinvolti nel pacchetto ad
. Ad esempio, il seguente funziona perfettamente:Tipi accettabili nelle funzioni Numeric.AD
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
ha il tipo:
grad
:: (Num a, Traversable f) =>
(forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
-> f a -> f a
Se cambio la firma tipo di ex
-[Double] -> Double
e provo la stessa cosa, ottengo
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 qualsiasi tipo di costruttore con tipo *
che crea un'istanza Num
.
Quando il Traversable f
è un elenco, il primo argomento di grad
deve avere tipo [AD s a] -> AD s a
per qualche accettabile Mode
- esempio Reverse
. Ma chiaramente l'utente di grad
non ha a che fare direttamente con il costruttore AD
o con lo Mode
. Sbirciando in questi interni mi ha lasciato un po 'confuso; nello specifico, non posso seguire il tipo/tipo di traccia per la differenza tra l'utilizzo di Num a => [a] -> a
e [Double] -> Double
.
Perché la firma del tipo [Double] -> Double
causa problemi con grad
? E in termini di semplice utilizzo della vecchia libreria: esiste un modo per utilizzare la versione [Double] -> Double
di ex
oppure è necessaria una versione polimorfa?
(titolo ispirato this similar question)
Ahhhh ok, quindi 'AD' è un'istanza di' Num'. Non l'ho notato nella lista delle istanze, ma ora lo vedo. – jtobin
Inoltre, se alcune costanti si trovano in posizione doppia, ad esempio in altre strutture di dati, potrebbe essere necessario utilizzare Numeric.AD.Types.lift o gli altri combinatori in modalità per fare in modo che interagiscano con gli argomenti di annuncio Double Argomenti e risultato . –