5

Estoy teniendo poco éxito en mi trabajo con la fontanería básica de los tipos implicados en el paquete ad. Por ejemplo, la siguiente funciona perfectamente:Tipos aceptables en las funciones de 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] 

donde 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 de la firma tipo de ex-[Double] -> Double y tratar de 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 se produce al reemplazar Double con aparentemente cualquier tipo constructor con tipo * que crea instancias Num.

Cuando el Traversable f es una lista, el primer argumento de grad debe tener un tipo [AD s a] -> AD s a por alguna aceptable Mode - por ejemplo, Reverse. Pero claramente el usuario de grad no tiene que tratar directamente con el constructor AD o el Mode. Echar un vistazo a estas partes internas me ha dejado un poco confundido; específicamente, no puedo seguir el rastro de tipo/tipo a la diferencia entre usar Num a => [a] -> a y [Double] -> Double.

¿Por qué la firma tipo [Double] -> Double causa problemas con grad? Y en términos del uso simple de la biblioteca anterior: ¿hay alguna forma de utilizar la versión [Double] -> Double de ex, o es una versión polimórfica necesaria?

(título inspirado por this similar question)

Respuesta

6

no sé la biblioteca ad, pero desde grad espera una función del tipo [AD s a] -> AD s a como primer parámetro, no se puede esperar a ser capaz de pasarlo en función del tipo de [Double] -> Double, desde Double y AD son tipos completamente diferentes.

La función genérica con Num restricción funciona, porque AD sí mismo es también una instancia de Num, por lo tanto, en su ejemplo de trabajo, ex consigue especializado para algo así como

ex :: (Mode s, Fractional a) => [AD s a] -> AD s a 

Si desea especializarse ex para los cálculos utilizando Dobles, necesita darle una firma como

ex :: Mode s => [AD s Double] -> AD s Double 
+0

Ahhhh ok, entonces 'AD' es una instancia de' Num'. No lo noté en la lista de instancias, pero ahora lo veo. – jtobin

+2

Además, si tiene algunas constantes en Dobles, por ejemplo, en otras estructuras de datos, es posible que necesite usar Numeric.AD.Types.lift o los otros combinadores en Modo para que interactúen con los argumentos dobles y el resultado de su AD. . –

Cuestiones relacionadas