2012-04-14 12 views
2

Haskell Neuling wissen will, warum die ersten 3 waren in Ordnung, aber die vierte Aussage explodierte:Haskell lesen Typinferenz

Prelude> read "5.3" + 5.0     -- ok 
10.3 

Prelude> read "5" + 5      -- ok 
10 

Prelude> read "5" + 5.3     -- ok 
10.3 

Prelude> read "5.3" + 5      -- huh ??? 
*** Exception: Prelude.read: no parse 

Ich sehe, dass: t 5,3 Fractional ist während 5 nur Num ist, aber beide müssen returnable von lesen, weil die ersten drei Befehle funktionierten, und (+) sollte auf jedem Paar von Nums funktionieren. Was ist denn hier los ?

+0

Sie können den Typ explizit angeben: '(lesen Sie" 5.3 ":: Double) + 5' –

Antwort

9

Wenn der Typ eines numerischen Ausdrucks mehrdeutig ist, versucht Haskell, ihn zuerst zu Integer und dann zu Double (eine Fließkommazahl) aufzulösen, falls das nicht funktioniert. Dies liegt daran, dass es ziemlich ärgerlich wäre, die Typen für einfache arithmetische Ausdrücke explizit anzugeben.

Dieses spezifische Beispiel geschah, weil 5.3 kein Integer sein kann (da Integer ist nicht Fractional), so beschlossen es zu Double in diesem Fall. Aber da 5 ein Integer sein kann, und read "5.3" kann jeder Typ sein, der gelesen werden kann, wurde es auf Integer voreingestellt, und blies zur Laufzeit auf, da 5.3 kein gültiges Integer Literal ist.

Wenn Sie -Wall aktivieren, können Sie sehen, dass diese Art von Fehler auftritt; Es wird eine Warnung angezeigt, wenn dies der Fall ist. (Dies ist jedoch in der Praxis ziemlich ärgerlich, da solche Fehler in GHCi sehr häufig vorkommen.)

+0

Danke für die schnelle Antwort . Jetzt sehe ich, dass Sie nicht tun können (5 :: Float) + (5 :: Integer) und dass mein 4. Befehl dazu aufgelöst wird. Dennoch bin ich überrascht, dass die Inferenztypisierung keine anderen Zweige versucht - z. Geh zurück und versuche, 5 zu etwas anderem zu lösen, zumindest wenn es sich um eingebaute Operatoren handelt. – tpascale

+6

Es kann nicht "zurückgehen", weil die Typprüfung vor der Ausführung stattfindet. Und der String wird nur während der Ausführung gelesen. – augustss