2014-09-17 26 views
5

Say ktoś chce obliczyć funkcję:Dlaczego mod daje inny wynik w wyrażeniu niż w wywołaniu funkcji?

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

Następnie, jeśli jedna rozszerza f (-1,0) ręcznie, dostaje:

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

Jeśli jednak używa funkcji inline, wynik jest:

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

Co dzieje się podczas zapisywania funkcji, która nie daje oczekiwanego rezultatu?

Zakładam, że to dlatego, że f używa Integral zamiast Int?

+0

BTW (i rzeczywiście blisko związany z problemem): nie potrzebujesz wszystkich tych parens; 'mod' wiąże się automatycznie mocniej (' infixl 7 mod' vs 'infixl 6 +'). Nic ci nie jest z '' ((-1) 'mod'3 + 0'mod'3)' mod' 2''. – leftaroundabout

+0

@leftaroundabout: Prawda, dodano nawiasy, aby wyśledzić problem :( –

Odpowiedz

9

Wygląda na to, że jest to kwestia parsowania. -1 `mod` 3 zostanie przeanalizowany jako -(1 `mod` 3), a nie (-1) `mod` 3.

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

Szczerze mówiąc, sposób unarne - prace w Haskell jest bit hack, które ja osobiście uważam mylące. Jeśli naprawdę potrzebuję negatywnego dosłowności, zwykle dodaję dodatkowe nawiasy, żeby się upewnić.

Kolejną rzeczą wymagającą rozważenia jest to, że Haskell ma dwa funkcji modulo mod i rem, które traktują liczb ujemnych inaczej. Aby uzyskać więcej informacji, należy zapoznać się z innymi pytaniami na temat: thesetwo.

+0

To dość dziwne, biorąc pod uwagę dokumentację [tutaj] (http://zvon.org/other/haskell/Outputprelude/mod_f.html) wydaje się zasugerować, że eksperymenty są wykonywane z ujemnymi licznikami: –

+0

@CommuSoft ta strona jest trochę ułomna – luqui

+0

W większości języków programowania, jednoargumentowy minus wiąże się prawdopodobnie z najbardziej zmiennymi, oczywiście teraz jest już za późno, ale może oni lepiej biorąc pod uwagę minus wyższy priorytet –

Powiązane problemy