2014-04-10 12 views
8

Mam pytanie związane z Data.List i podpisem deleteBy. Idealnie funkcja powinna przyjmować predykat i usuwać pierwszy element, dla którego predykat jest prawdziwy. Coś jak:Dlaczego dane Haskell Data.List.deleteBy przyjmuje funkcję porównania (a -> a -> Bool) i wartość zamiast predykatu (a -> Bool)?

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

Zamiast funkcja zdefiniowana w bibliotece trwa zarówno orzecznik i wartość:

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 

Łatwo zauważyć, że eq jest zawsze używany z x jako pierwszy argument i x jest stała w deleteBy, więc nie ma powodu, aby uzyskać eq i x zamiast eq x. Z drugiej strony, biorąc predykat pracujący nad jednym elementem, można przekazać predykaty, które nie porównują dwóch wartości, takich jak funkcja działająca na części typu a lub funkcja trywialna, taka jak cons true. Moje pytanie brzmi: dlaczego deleteBy zostało zaimplementowane w ten sposób?

+2

Ważne odpowiedzi: http://stackoverflow.com/questions/9004937/is-there-a-good-reason-why-deleteby-does-not-have-itsa-most-general-type. Spójność z typem '(==)' brzmi jak wiarygodne wyjaśnienie. – duplode

+1

prosty do obejścia (func const) – PyRulez

Odpowiedz

11

Funkcja jest uogólnieniem delete, dlatego warto najpierw zapoznać się z delete.

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

delete przyjmuje wartość Eq a => a, a następnie usuwa się z pierwszego występowaniu gazów tej wartości z [a] pomocą (==) z przykładu Eq.

jak ze wszystkimi *By funkcji w Data.List The Eq ograniczeniem jest usuwany i programista jest zobowiązany do przedstawienia własnego wymiana (==) funkcję.

więc usunięcie z deleteEq ograniczenie i zastąpienie go rodzaju (==), mianowicie a -> a -> Bool, daje rodzaj deleteBy.

Innymi słowy, chodzi o spójność z pozostałymi operacjami *By w Data.List.

+0

Które wszystkie sugerują 'deleteBy' powinny być podane w kategoriach bardziej ogólnej funkcji. – dfeuer

0

Jak wskazują cdk i inne. Jest to uogólnienie względem predykatu równości.

Funkcja, o którą pytasz, to "usuń elementy z listy, które pasują do tego predykatu". Jest to bardziej zbliżone do pojedynczego elementu filter.

Funkcja "usuń element x, ale użyj tego operatora porównania zamiast (==)".

Powiązane problemy