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)
Ahhhh ok, also 'AD' ist eine Instanz von' Num'. Ich habe das in der Instanzenliste nicht bemerkt, aber ich sehe es jetzt. – jtobin
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 . –