2014-09-17 8 views
5

Say will man die Funktion berechnen:Warum gibt Mod in einem Ausdruck ein anderes Ergebnis als in einem Funktionsaufruf?

f (x,y) = ((x `mod` 3)+(y `mod` 3)) `mod` 2 

Wenn dann ein f (-1,0) manuell erweitert wird, erhält man:

((-1 `mod` 3)+(0 `mod` 3)) `mod` 2 
1 

Wenn man jedoch eine Inline-Funktion verwendet, ist das Ergebnis:

let f (x,y) = ((x `mod` 3)+(y `mod` 3)) `mod` 2 in f (-1,0) 
0 

Was passiert beim Speichern der Funktion, die nicht das erwartete Ergebnis liefert?

Ich nehme an, das ist, weil fIntegral statt Int verwendet?

+0

BTW (und in der Tat eng mit dem Problem verbunden): Sie brauchen nicht alle diese Parens; 'mod' bindet automatisch fester (' infixl 7 mod' vs. 'infixl 6 +'). Es wäre in Ordnung mit '' ((-1) 'mod'3 + 0'mod'3)' mod' 2''. – leftaroundabout

+0

@leftaroundabout: Richtig, die Klammern wurden hinzugefügt, um das Problem aufzuspüren :(. –

Antwort

9

Sieht aus wie es ist eine Frage des Parsens. -1 `mod` 3 wird als -(1 `mod` 3) und nicht (-1) `mod` 3 geparst.

*Main> -(1 `mod` 3) 
-1 
*Main> (-1) `mod` 3 
2 

Ehrlich gesagt, die Art und Weise einstelligen - Werke in Haskell ist ein bisschen wie ein Hack, die ich persönlich verwirrend finden. Wenn ich wirklich ein negatives Literal brauche, füge ich normalerweise nur die zusätzlichen Klammern hinzu.

Eine andere Sache zu prüfen ist, dass Haskell zwei Modulo Funktionen, mod und rem, die unterschiedlich negative Zahlen zu behandeln. Weitere Details finden Sie unter thesetwo andere Fragen.

+0

Das ist ziemlich seltsam, angesichts der Dokumentation [hier] (http://zvon.org/other/haskell/Outputpreludeus/mod_f.html) –

+0

@CommuSoft Ja, diese Seite ist irgendwie lahm – luqui

+0

In den meisten Programmiersprachen bindet das unäre Minus wahrscheinlich am meisten an Variable, natürlich ist es jetzt zu spät, aber vielleicht hatten sie es besser gegebener Minuspunkt mehr Priorität –