Sprawdzanie wszystkich elementów w zestawie w Haskell przy użyciu cukru syntaktycznego

Nov 21 2020

Próbuję usunąć całkowite duplikaty listy (String, Int), gdzie mam gwarancję, że nie ma Stringduplikató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

2 WillNess Nov 21 2020 at 10:53

(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)].

1 Niclas Nov 23 2020 at 17:02

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.

1 dfeuer Nov 23 2020 at 22:21

Istniejące odpowiedzi nie korzystają z gwarancji, że ciągi są unikalne ani z faktu, że Intsą 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 ]