2015-11-04 2 views
6

La funzione seguente dovrebbe generare numeri primi tuttavia non per GHC 7.10.2. Qualcun altro sta vedendo questo?nubBy non funziona come previsto

GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help 
Prelude> import Data.List 
Prelude Data.List> print . take 100 . nubBy (\x y -> x `rem` y == 0) $ [2..] 
[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101] 

La parte strana è che sembra funzionare bene su questo sito:

rextester.com/LWZCQ71376

+3

'nubBy' richiede una relazione di equivalenza, credo. – chi

+2

Questo è ciò che dicono i documenti e la funzione passata qui non lo è, il che comporterebbe un comportamento indefinito. In pratica, potrebbe ad es. sono stati riscritti in modo tale che gli argomenti siano applicati nell'ordine opposto (sicuro per le funzioni di equivalenza, non per funzioni arbitrarie come questa) –

+0

Funziona qui bene: http://rextester.com/LWZCQ71376 –

risposta

14

cosa è cambiato tra la base-4.7.x e base-4.8.0.0 è la definizione di elem_by che è ciò che nubBy è definito in termini di.

In base-4.7 elem_by ha questa clausola:

elem_by eq y (x:xs)  = y `eq` x || elem_by eq y xs 

e in base-4.8 è stato cambiato a:

elem_by eq y (x:xs)  = x `eq` y || elem_by eq y xs 

La storia di questo cambiamento è documentato in questi problemi TRAC:

Si noti che la versione Preludio Haskell Relazione del nubBy è:

nubBy eq (x:xs)   = x : nubBy eq (filter (\ y -> not (eq x y)) xs) 

che era in contrasto con l'implementazione di base-4.7, in modo che spiega anche il cambio.

+0

La funzione eq dovrebbe essere commutativa, sembra possibile che questo cambiamento possa essere la causa del mio problema. –

+4

No !! La tua funzione 'eq' NON è commutativa! 'rem 4 2/= rem 2 4'. Uno sarà uguale a zero mentre l'altro sarà due. –

+5

Penso che un termine migliore da usare sia _symmetric_. – ErikR

3

L'ordine degli argomenti è stato capovolto, sembra, nella nuova base. EDIT: Ho chiamato questo un bug, ma come un'altra risposta sottolinea il vecchio comportamento era l'ordine errato.

È possibile visualizzare l'ordine è stato capovolto osservando:

> print . take 5 . nubBy (\x y -> trace (show (x,y)) $ x `rem` y == 0) $ [2..] 
[2(2,3) 
,3(3,4) 
(2,4) 
,4(4,5) 
(3,5) 
(2,5) 

Certamente rem 2 4 non è uguale a zero (è uguale a 2), in modo che produce 4.

Avviso si ottiene il risultato desiderato quando si capovolge l'ordine argomento nella lambda:

> print . take 5 . nubBy (\x y -> trace (show (x,y)) $ y `rem` x == 0) $ [2..] 
[2(2,3) 
,3(3,4) 
(2,4) 
(3,5) 
(2,5) 
.... 

EDIT: Dal momento che la discussione indica il rapporto dovrebbe essere l'uguaglianza e operare indipendentemente dall'ordine (mi e' m troppo pigro per guardare il rapporto in questo momento) si noti è possibile confrontare gli argomenti prima di ottenere un comportamento stabile in entrambi i casi:

print . take 100 . nubBy (\x y -> rem (max x y) (min x y) == 0) $ [2..] 
+0

Si chiamerebbe questo un bug nella base GHC? –

+0

Certamente. Innanzitutto, definisci "bug" come comportamento contrario alle specifiche Haskell Language. Secondo, notare che questo comportamento era contrario. In terzo luogo, gridare "bug". –

+2

'(\ x y -> rem (max x y) (min x y) == 0)' potrebbe essere simmetrico, ma non è ancora una relazione di equivalenza. –