Question

J'ai peu de succès à comprendre la plomberie de base des types impliqués dans le ad emballer.Par exemple, ce qui suit fonctionne parfaitement :

import Numeric.AD

ex :: Num a => [a] -> a
ex [x, y] = x + 2*y

> grad ex [1.0, 1.0]
[1.0, 2.0]

grad a le type :

grad
  :: (Num a, Traversable f) =>
     (forall (s :: * -> *). Mode s => f (AD s a) -> AD s a)
     -> f a -> f a

Si je change la signature de type de ex à [Double] -> Double et j'essaye la même chose, j'obtiens

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

Le même comportement se produit lors du remplacement Double avec apparemment n'importe quel constructeur de type avec type * qui instancie Num.

Quand le Traversable f est une liste, le premier argument de grad doit avoir le type [AD s a] -> AD s a pour certains acceptable Mode - par exemple., Reverse.Mais il est clair que l'utilisateur de grad n'a pas à s'occuper du AD constructeur ou le Mode directement.Jeter un coup d’œil à ces éléments internes m’a laissé un peu confus ;plus précisément, je ne peux pas suivre la piste genre/type jusqu'à la différence entre l'utilisation Num a => [a] -> a et [Double] -> Double.

Pourquoi la signature de type [Double] -> Double causer des problèmes avec grad?Et en termes d'utilisation simple de la vieille bibliothèque :est-il possible d'utiliser le [Double] -> Double version de ex, ou une version polymorphe est-elle nécessaire ?

(titre inspiré de cette question similaire)

Était-ce utile?

La solution

je ne connais pas le ad bibliothèque, mais depuis grad attend une fonction de type [AD s a] -> AD s a comme premier paramètre, vous ne pouvez pas vous attendre à pouvoir lui passer une fonction de type [Double] -> Double, depuis Double et AD sont des types complètement différents.

La fonction générique avec Num la contrainte fonctionne, car AD lui-même est également un exemple de Num, donc dans votre exemple de travail, ex se spécialise dans quelque chose comme

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

Si vous souhaitez vous spécialiser ex pour les calculs utilisant Doubles, vous devez lui donner une signature telle que

ex :: Mode s => [AD s Double] -> AD s Double
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top