Tipos aceptables en funciones Numeric.AD
-
11-12-2019 - |
Pregunta
Estoy teniendo poco éxito entendiendo los conceptos básicos de plomería de los tipos involucrados en el ad
paquete.Por ejemplo, lo siguiente funciona perfectamente:
import Numeric.AD
ex :: Num a => [a] -> a
ex [x, y] = x + 2*y
> grad ex [1.0, 1.0]
[1.0, 2.0]
dónde grad
tiene el tipo:
grad
:: (Num a, Traversable f) =>
(forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
-> f a -> f a
Si cambio el tipo de firma de ex
a [Double] -> Double
y intento lo mismo, me sale
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
El mismo comportamiento ocurre al reemplazar Double
con aparentemente cualquier tipo constructor con tipo *
que instancia Num
.
Cuando el Traversable f
es una lista, el primer argumento de grad
debe tener tipo [AD s a] -> AD s a
para algunos aceptable Mode
- p.ej., Reverse
.Pero claramente el usuario de grad
no tiene que lidiar con el AD
constructor o el Mode
directamente.Echar un vistazo a estas partes internas me ha dejado un poco confundido;específicamente, no puedo seguir el rastro de tipo/tipo para la diferencia entre usar Num a => [a] -> a
y [Double] -> Double
.
¿Por qué la firma tipográfica [Double] -> Double
causar problemas con grad
?Y en términos del uso de la biblioteca antigua:¿Hay alguna forma de utilizar el [Double] -> Double
versión de ex
, ¿O es necesaria una versión polimórfica?
(título inspirado en esta pregunta similar)
Solución
no se el ad
biblioteca, pero desde grad
espera una función de tipo [AD s a] -> AD s a
como primer parámetro, no puede esperar poder pasarle una función de tipo [Double] -> Double
, desde Double
y AD
Son tipos completamente diferentes.
La función genérica con Num
La restricción funciona porque AD
en sí mismo es también un ejemplo de Num
, por lo tanto, en su ejemplo de trabajo, ex
se especializa en algo como
ex :: (Mode s, Fractional a) => [AD s a] -> AD s a
Si quieres especializarte ex
para cálculos usando Dobles, debe darle una firma como
ex :: Mode s => [AD s Double] -> AD s Double