2014-09-03 19 views
6

Sto appena iniziando a imparare la programmazione funzionale, La mia scelta è haskell. E 'stato ok per un paio di giorni fino a quando qualcosa bizzare accadere nella consoleHaskell che sputa a caso numeri errati

In un primo momento ho pensato che il tutorial (http://learnyouahaskell.com/starting-out) è sbagliato

Prelude> [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2] 
[(1,1,1)] 

Dovrebbe essere (3,4,5) e (4,6,8). Ho provato 3^2+5^2, sputa fuori questo numero di numeri (qualcosa come 60 righe di numeri, circa 3000 cifre); 4^2+3^2 sembra produrre gli stessi numeri.

Cercando di aggiungere tutti i numeri il risultato sarà 100

Prelude> 100 + 200 
100 
Prelude> 300 + 500 
100 

I chiudere la finestra e riaprirlo e il problema è risolto.

Questo calcolo errato si è verificato spesso in Haskell? o forse la mia versione di Haskell è danneggiata durante il download? o Qualche possibilità che questo sia un bug raro?

+6

Sei sicuro che non hai fatto qualcosa di simile a 'lasciare che un + b = 100' prima di eseguire quella linea? Non riesco a replicare i risultati, e le definizioni di let in ghci sono piuttosto stateful. – BluePeppers

+0

Inoltre, l'output corretto dovrebbe probabilmente essere '[(3,4,5), (6,8,10)]', che è quello che ottengo (e corrisponde sia alla pagina di Wikipedia che alla mia educazione matematica come i primi 2 Tripli pitagorici) – BluePeppers

+0

@BluePeppers Penso che ce l'abbia, perché dopo 'lascia un + b = 100', quella comprensione di lista * fa * dà' [(1,1,1)] '. –

risposta

11

Quello che sta accadendo, come suggerito da @BluePeppers, è che hai in qualche modo fatto l'equivalente di let a+b = 100 in ghci, dopo di che usa quella definizione invece del solito + in tutte le tue espressioni.

si potrebbe ancora chiedere perché che dà tali numeri enormi, e così ho fatto fino a quando ho capito che il secondo punto: Ridefinire (+) ridefinisce anche la sua la precedenza, al default di 9 (più alto). Così i vostri esempi diventano interpretati come:

[ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2] 

diventa

[ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^100^2 == c^2] 

e

3^2+5^2 

diventa

3^100^2 
+0

Oh questo è anche meglio di quanto mi aspettassi. Che bello – BluePeppers

+0

aah, non sapevo che haskell può scavalcare un operatore. – Rmxhaha

+0

Ho pensato che haskell può risolvere il problema di aljebra, quindi l'ho provato prima di provare il tutorial, – Rmxhaha