Frage

Ich habe wenig Erfolg damit, meinen Kopf um die grundlegenden Klempnerarbeiten der Typen zu wickeln, die an der ad Paket.Zum Beispiel funktioniert Folgendes perfekt:

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 hat den Typ:

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

Wenn ich die Typensignatur von ändere ex zu [Double] -> Double und versuche das gleiche, ich verstehe

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 beim Ersetzen auf Double mit scheinbar jedem Typkonstruktor mit Art * das instanziiert Num.

Wenn der Traversable f ist eine Liste, das erste Argument von grad muss Typ haben [AD s a] -> AD s a für einige akzeptabel Mode - beispielsweise., Reverse.Aber eindeutig der Benutzer von grad muss sich nicht mit dem beschäftigen AD konstruktor oder der Mode direkt.Ein Blick in diese Interna hat mich etwas verwirrt;insbesondere kann ich der Art / Typ-Spur nicht zum Unterschied zwischen der Verwendung folgen Num a => [a] -> a und [Double] -> Double.

Warum funktioniert die Typensignatur [Double] -> Double probleme verursachen mit grad?Und in Bezug auf die einfache alte Bibliotheksnutzung:gibt es eine Möglichkeit, das zu verwenden [Double] -> Double version von ex, oder ist eine polymorphe Version notwendig?

(titel inspiriert von diese ähnliche Frage)

War es hilfreich?

Lösung

Ich kenne das nicht ad bibliothek, aber seit grad erwartet eine Funktion vom Typ [AD s a] -> AD s a als erster Parameter können Sie nicht erwarten, dass ihm eine Funktion vom Typ übergeben werden kann [Double] -> Double, da Double und AD sind völlig verschiedene Typen.

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

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

Wenn Sie sich spezialisieren möchten ex für Berechnungen mit Doppelwerten müssen Sie ihm eine Signatur geben, z

ex :: Mode s => [AD s Double] -> AD s Double
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top