"Haskell erlaubt das Vergleichen verschiedener numerischer Typen" nein, tut es nicht. Was Haskell tatsächlich zulässt, sind verschiedene Typen, die durch dieselben Literale definiert werden. Insbesondere können Sie tun
Prelude> let a = 3.7 :: Double
Prelude> let b = 1 :: Double
Prelude> a + b
4.7
OTOH, wenn ich diese explizit mit widersprüchlichen Typen deklariert, würde die Zugabe fehlschlagen:
Prelude> let a = 3.7 :: Double
Prelude> let b = 1 :: Int
Prelude> a + b
<interactive>:31:5:
Couldn't match expected type ‘Double’ with actual type ‘Int’
In the second argument of ‘(+)’, namely ‘b’
In the expression: a + b
Nun Double
ist nicht die allgemeinste mögliche Art für entweder a
oder b
. Tatsächlich sind alle Zahlenliterale polymorph, aber bevor irgendeine Operation (wie Gleichheitsvergleich) stattfindet, muss ein solcher polymorpher Typ auf eine konkrete monomorphe Art festgelegt werden. Wie,
Prelude> (3.0 :: Double) == (3 :: Double)
True
Weil ==
, im Gegensatz zu Ihrer Prämisse, erfordert tatsächlich beide Seiten die gleiche Art haben, können Sie die Unterschrift auf beiden Seiten auslassen ohne etwas zu ändern:
Prelude> 3.0 == (3 :: Double)
True
In der Tat, auch ohne irgendeine Art Anmerkung, GHCi behandelt immer noch beide Seiten als Double
. Dies liegt an type defaulting - in diesem speziellen Fall ist Fractional
die stärkste Einschränkung für den Typ mit gemeinsam genutzter Nummer, und für Fractional
ist der Standardtyp Double
. OTOH, wenn beide Seiten integrale Literale gewesen wären, dann hätte GHCi Integer
gewählt. Dies kann manchmal einen Unterschied machen, zum Beispiel
Prelude> 10000000000000000 == 10000000000000001
False
aber
Prelude> 10000000000000000 ==(10000000000000001 :: Double)
True
weil im letzteren Fall wird die endgültigen 1 in den Floating-Point-Fehlern verloren.
Dies ist nur ein Beispiel für (erweiterte?) Standardregeln in GHCi. – crockeea
Ein vielleicht verwirrender Punkt hier: obwohl '3' und' 3.0' unterschiedliche polymorphe Typen haben, im Ausdruck '3 == 3.0 ', erhalten beide den gleichen monomorphen Typ, bevor die Gleichheit berechnet wird. Der Typ von '(==)' besagt, dass er zwei Argumente des gleichen Typs akzeptieren muss: 'Eq a => a -> a -> Bool '. Ich vermute, dass Missverständnisse diese Subtilität zu der Frage führen. –
"ermöglicht den Vergleich verschiedener numerischer Typen". Probieren Sie es aus: 'length" abc "== 3.0'. Funktioniert es? –