2009-06-11 1 views
4

Ich brauche die Numeric.FAD-Bibliothek, obwohl sie immer noch komplett von existentiellen Typen verwirrt ist.Was ist mit "abgeleiteter Typ ist weniger polymorph als erwartet" zu tun?

Dies ist der Code:

error_diffs :: [Double] -> NetworkState [(Int, Int, Double)] 
error_diffs desired_outputs = do diff_error <- (diff_op $ error' $ map FAD.lift desired_outputs)::(NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double)) 
           weights <- link_weights 
           let diffs = FAD.grad (diff_error::([FAD.Dual tag a] -> FAD.Dual tag b)) weights 

           links <- link_list 
           return $ zipWith (\link diff -> 
                 (linkFrom link, linkTo link, diff) 
               ) links diffs 

error‘ein Leser monadisch läuft in lief durch diff_op, die wiederum eine anonyme Funktion den aktuellen NetworkState und die Differenzeingänge von FAD.grad und stopft aufzunehmen erzeugt sie in den Leser.

Haskell verwirrt mich mit den folgenden:

Inferred type is less polymorphic than expected 
    Quantified type variable `tag' is mentioned in the environment: 
    diff_error :: [FAD.Dual tag Double] -> FAD.Dual tag Double 
     (bound at Operations.hs:100:33) 
In the first argument of `FAD.grad', namely 
    `(diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b)' 
In the expression: 
    FAD.grad (diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights 
In the definition of `diffs': 
    diffs = FAD.grad 
       (diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights 

Antwort

3

Wenn ich schreibe,

bigNumber :: (Num a) => a 
bigNumber = product [1..100] 

dann, wenn bigNumber :: Int ausgewertet wird,
es Auswertung (product :: [Int] -> Int) [(1 :: Int) .. (100 :: Int)],

und wenn bigNumber :: Integer ausgewertet ,
es bewertet (product :: [Integer] -> Integer) [(1 :: Integer) .. (100 :: Integer)].

Nichts wird zwischen den beiden geteilt.

error_diffs hat einen einzigen Typ, nämlich: [Double] -> NetworkState [(Int, Int, Double)]. Es muss genau auf eine Art ausgewertet werden.

jedoch, was Sie innen haben:

... :: NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double) 

kann auf verschiedene Weise ausgewertet werden, je nachdem, was tag ist.

Sehen Sie das Problem?

+1

Nein, tut mir leid. Ich habe keine Ahnung, welchen Zweck die Variablen des Tag-Typs haben. Wie soll ich mit Numeric.FAD umgehen? Alles, was ich brauche, ist Ableitung. – Astro

+0

Siehe http://thread.gmane.org/gmane.comp.lang.haskell.cafe/22308/ für eine Diskussion über das von FAD verwendete "Tagging". Ich habe Numeric.FAD nicht installiert, daher kann ich Ihnen bei der Umstrukturierung Ihres Codes noch nicht helfen. Vielleicht können Sie es selbst ausprobieren, mit Hinweisen aus diesem Artikel? – ephemient

4

dieser Code gibt den gleichen Fehler wie Sie bekommen:

test :: Int 
test = 
    (res :: Num a => a) 
    where 
    res = 5 

Der Compiler dachte, dass res ist immer vom Typ Int und wird gestört, dass Sie aus irgendeinem Grund denken res polymorph ist.

dieser Code funktioniert aber fein:

test :: Int 
test = 
    res 
    where 
    res :: Num a => a 
    res = 5 

auch hier res als polymorphe definiert, aber immer nur als Int verwendet. Der Compiler wird nur belästigt, wenn Sie verschachtelte Ausdrücke auf diese Weise eingeben. In diesem Fall res könnte wiederverwendet werden und möglicherweise eine dieser Verwendungen wird es nicht als Int verwenden, im Gegensatz zu, wenn Sie einen verschachtelten Ausdruck eingeben, der nicht von selbst wiederverwendet werden kann.