5

Ich habe wenig Erfolg, meinen Kopf um die grundlegenden Rohrleitungen der Typen zu wickeln, die im ad-Paket enthalten sind. Zum Beispiel arbeitet die folgende perfekt:Akzeptable Typen in Numeric.AD-Funktionen

import Numeric.AD 

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

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

wo grad den Typ hat:

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

Wenn ich die Art Signatur von ex-[Double] -> Double ändern und versuchen, die gleiche Sache, ich

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 

Das gleiche Verhalten tritt auf, wenn Double mit scheinbar jedem Typkonstruktor mit Artersetzt wird, das Num instanziiert.

Wenn die Traversable f eine Liste ist, muss das erste Argument von grad Typs haben [AD s a] -> AD s a für einige akzeptable Mode - z.B. Reverse. Aber eindeutig muss sich der Benutzer von grad nicht direkt mit dem AD Konstruktor oder dem Mode befassen. Ein Blick in diese Interna hat mich ein wenig verwirrt; Insbesondere kann ich die Art/Typ-Trail nicht auf den Unterschied zwischen der Verwendung von Num a => [a] -> a und [Double] -> Double folgen.

Warum verursacht die Typensignatur [Double] -> Double Probleme mit grad? Und in Bezug auf die einfache alte Bibliothek verwenden: gibt es eine Möglichkeit, die [Double] -> Double Version von ex zu verwenden, oder ist eine polymorphe Version notwendig?

(Titel von this similar question inspiriert)

Antwort

6

ich weiß nicht, die ad Bibliothek, aber da grad eine Funktion vom Typ erwartet [AD s a] -> AD s a als ersten Parameter, kann man nicht erwarten, dass es eine Funktion vom Typ passieren [Double] -> Double, seit Double und AD sind völlig verschiedene Arten.

Die generische Funktion mit Num Einschränkung funktioniert, weil AD selbst ist auch eine Instanz von Num daher in Ihrem Arbeitsbeispiel ex wie auf etwas spezialisiert wird

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

Wenn Sie ex für Berechnungen spezialisieren wollen mit Doubles, Sie müssen es eine Signatur wie

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

Ahhhh ok, also 'AD' ist eine Instanz von' Num'. Ich habe das in der Instanzenliste nicht bemerkt, aber ich sehe es jetzt. – jtobin

+2

Auch wenn Sie einige Konstanten als Doubles haben, sagen wir, in anderen Datenstrukturen, müssen Sie möglicherweise Numeric.AD.Types.lift oder die anderen Kombinatoren im Modus verwenden, damit diese mit Ihren AD s Double Argumenten und dem Ergebnis interagieren . –