Sprawdzanie wszystkich elementów w zestawie w Haskell przy użyciu cukru syntaktycznego
Próbuję usunąć całkowite duplikaty listy (String, Int)
, gdzie mam gwarancję, że nie ma String
duplikatów.
Czy można ocenić coś takiego w Haskellu:
Próbowałem:
[(a,b) | (a,b) <- bs, (c,k) <- bs, ((k == b) <= (a == c))]
ale to jeszcze nie działa.
Edycja: Zdaję sobie sprawę, że można to osiągnąć używając bardziej złożonej składni. Na przykład przez rekurencyjne przeszukiwanie listy pod kątem duplikatów każdego elementu ...
Odpowiedzi
(Uwaga: to jest zupełnie nowa wersja tej odpowiedzi. Poprzednia była całkowicie poza bazą).
Aby dokładniej śledzić Twoje rozumienie zestawu matematycznego, możemy dostosować definicję w Twojej odpowiedzi jako
uniquesOnly :: (Eq a, Eq b) => [(a, b)] -> [(a, b)]
uniquesOnly bs =
[(a,b) | (a,b) <- bs,
[(c,d) | (c,d) <- bs, d == b] ==
[(a,d) | (c,d) <- bs, d == b]]
"dla wszystkich (c, d) w bs takich, że d == b następuje c == a".
uniquesOnly [(1,1),(2,2),(3,1)]
zwraca [(2,2)]
.
To jest możliwe rozwiązanie:
Na przykład ułożyłem to równoważne stwierdzenie:
removeDuplicates :: [(String, Int)] -> [(String, Int)]
removeDuplicates bs =
[(a,b) | (a,b) <- bs,
length [(c,d) | (c,d) <- bs, d == b] == 1]
Ale to nie jest to samo stwierdzenie, tylko równe.
Istniejące odpowiedzi nie korzystają z gwarancji, że ciągi są unikalne ani z faktu, że Int
są one uporządkowane. Oto jeden, który tak robi.
import Data.List (sortBy, groupBy)
import Data.Function (on)
uniquesOnly :: Ord b => [(a, b)] -> [(a, b)]
uniquesOnly ps
= [ p
| [p] <- groupBy ((==) `on` snd) .
sortBy (compare `on` snd) $ ps ]