2014-04-10 14 views
8

Ho una domanda relativa a Data.List e la firma di deleteBy. Idealmente questa funzione dovrebbe contenere un predicato ed eliminare il primo elemento per il quale il predicato è vero. Qualcosa di simile:Perché Haskell's Data.List.deleteBy accetta in input una funzione di confronto (a -> a -> Bool) e un valore invece di un predicato (a -> Bool)?

deleteBy :: (a -> Bool) -> [a] -> [a] 
deleteBy p = go 
    where go []     = [] 
      go (x:xs) | p x   = xs 
        | otherwise = x:go xs 

Invece la funzione definita nella libreria prende sia un predicato e un valore:

deleteBy    :: (a -> a -> Bool) -> a -> [a] -> [a] 
deleteBy _ _ []  = [] 
deleteBy eq x (y:ys) = if x `eq` y then ys else y : deleteBy eq x ys 

E 'facile vedere che eq viene sempre utilizzato con x come primo argomento e x è fisso in deleteBy, quindi non c'è motivo di ottenere sia eq e x anziché eq x. Al contrario, eseguendo un predicato su un singolo elemento è possibile passare predicati che non confrontano due valori, ad esempio una funzione che funziona su una parte del tipo a o una funzione banale come cons true. La mia domanda è: perché deleteBy è stato implementato in questo modo?

+2

Risposte pertinenti: http://stackoverflow.com/questions/9004937/is-there-a-good-reason-why-deleteby-does-not-have-its-most-general-type. La coerenza con il tipo di '(==)' suona come una spiegazione plausibile. – duplode

+1

semplice da aggirare (func const) – PyRulez

risposta

11

La funzione deleteBy è una generalizzazione di delete, quindi è utile dare un'occhiata a delete prima.

delete :: Eq a => a -> [a] -> [a] 

delete assume un valore Eq a => a, quindi elimina la prima occorrenza di tale valore dalla [a] usando l'(==) dall'istanza Eq.

Come con tutte le funzioni *ByData.List, il vincolo Eq viene rimosso ed il programmatore è tenuto a fornire la propria funzione di sostituzione (==).

Quindi la rimozione del vincolo Eq da delete e la sua sostituzione con il tipo di (==), vale a dire a -> a -> Bool, ti dà il tipo di deleteBy.

In altre parole, è per coerenza con il resto delle operazioni *By in Data.List.

+0

Che tutti suggeriscono 'deleteBy' dovrebbe essere dato in termini di funzione più generale. – dfeuer

0

Come cdk e altri sottolineano. È generalizzare sul predicato di uguaglianza.

La funzione richiesta è "elimina elementi nell'elenco che corrispondono a questo predicato". Questo è più simile al singolo elemento filter.

La funzione deleteBy è 'delete element x, ma utilizzare questo operatore di confronto invece di (==)'.

Problemi correlati