module Data.AssocList.List.Equivalence
(
lookupFirst
, lookupAll
, removeFirst
, removeAll
, mapFirst
, mapAll
, alterFirst
, alterAll
, partition
, break
, breakPartition
) where
import Data.AssocList.List.Concept
import qualified Data.List
import Data.Maybe (maybeToList)
import Prelude (Maybe (..), (++), (<$>), otherwise)
import Data.Functor.Contravariant (Equivalence (..))
lookupFirst :: Equivalence a -> a -> AssocList a b -> Maybe b
lookupFirst :: Equivalence a -> a -> AssocList a b -> Maybe b
lookupFirst Equivalence a
_eq a
_key [] = Maybe b
forall a. Maybe a
Nothing
lookupFirst Equivalence a
eq a
key ((a
x, b
y) : AssocList a b
xys)
| Equivalence a -> a -> a -> Bool
forall a. Equivalence a -> a -> a -> Bool
getEquivalence Equivalence a
eq a
key a
x = b -> Maybe b
forall a. a -> Maybe a
Just b
y
| Bool
otherwise = Equivalence a -> a -> AssocList a b -> Maybe b
forall a b. Equivalence a -> a -> AssocList a b -> Maybe b
lookupFirst Equivalence a
eq a
key AssocList a b
xys
lookupAll :: Equivalence a -> a -> AssocList a b -> [b]
lookupAll :: Equivalence a -> a -> AssocList a b -> [b]
lookupAll Equivalence a
_eq a
_key [] = []
lookupAll Equivalence a
eq a
key ((a
x, b
y) : AssocList a b
xys)
| Equivalence a -> a -> a -> Bool
forall a. Equivalence a -> a -> a -> Bool
getEquivalence Equivalence a
eq a
key a
x = b
y b -> [b] -> [b]
forall a. a -> [a] -> [a]
: Equivalence a -> a -> AssocList a b -> [b]
forall a b. Equivalence a -> a -> AssocList a b -> [b]
lookupAll Equivalence a
eq a
key AssocList a b
xys
| Bool
otherwise = Equivalence a -> a -> AssocList a b -> [b]
forall a b. Equivalence a -> a -> AssocList a b -> [b]
lookupAll Equivalence a
eq a
key AssocList a b
xys
removeFirst :: Equivalence a -> a -> AssocList a b -> AssocList a b
removeFirst :: Equivalence a -> a -> AssocList a b -> AssocList a b
removeFirst Equivalence a
_eq a
_key l :: AssocList a b
l@[] = AssocList a b
l
removeFirst Equivalence a
eq a
key (xy :: (a, b)
xy@(a
x, b
y) : AssocList a b
xys)
| Equivalence a -> a -> a -> Bool
forall a. Equivalence a -> a -> a -> Bool
getEquivalence Equivalence a
eq a
key a
x = AssocList a b
xys
| Bool
otherwise = (a, b)
xy (a, b) -> AssocList a b -> AssocList a b
forall a. a -> [a] -> [a]
: Equivalence a -> a -> AssocList a b -> AssocList a b
forall a b. Equivalence a -> a -> AssocList a b -> AssocList a b
removeFirst Equivalence a
eq a
key AssocList a b
xys
removeAll :: Equivalence a -> a -> AssocList a b -> AssocList a b
removeAll :: Equivalence a -> a -> AssocList a b -> AssocList a b
removeAll Equivalence a
_eq a
_key l :: AssocList a b
l@[] = AssocList a b
l
removeAll Equivalence a
eq a
key (xy :: (a, b)
xy@(a
x, b
y) : AssocList a b
xys)
| Equivalence a -> a -> a -> Bool
forall a. Equivalence a -> a -> a -> Bool
getEquivalence Equivalence a
eq a
key a
x = Equivalence a -> a -> AssocList a b -> AssocList a b
forall a b. Equivalence a -> a -> AssocList a b -> AssocList a b
removeAll Equivalence a
eq a
key AssocList a b
xys
| Bool
otherwise = (a, b)
xy (a, b) -> AssocList a b -> AssocList a b
forall a. a -> [a] -> [a]
: Equivalence a -> a -> AssocList a b -> AssocList a b
forall a b. Equivalence a -> a -> AssocList a b -> AssocList a b
removeAll Equivalence a
eq a
key AssocList a b
xys
partition :: Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
partition :: Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
partition Equivalence a
_eq a
_key l :: AssocList a b
l@[] = ([], AssocList a b
l)
partition Equivalence a
eq a
key (xy :: (a, b)
xy@(a
x, b
y) : AssocList a b
xys)
| Equivalence a -> a -> a -> Bool
forall a. Equivalence a -> a -> a -> Bool
getEquivalence Equivalence a
eq a
key a
x = (b
y b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b]
yes , AssocList a b
no)
| Bool
otherwise = ( [b]
yes , (a, b)
xy (a, b) -> AssocList a b -> AssocList a b
forall a. a -> [a] -> [a]
: AssocList a b
no)
where
([b]
yes, AssocList a b
no) = Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
forall a b.
Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
partition Equivalence a
eq a
key AssocList a b
xys
break :: Equivalence a -> a -> AssocList a b -> (AssocList a b, AssocList a b)
break :: Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
break Equivalence a
eq a
key = ((a, b) -> Bool) -> AssocList a b -> (AssocList a b, AssocList a b)
forall a. (a -> Bool) -> [a] -> ([a], [a])
Data.List.break (\(a
x, b
y) -> Equivalence a -> a -> a -> Bool
forall a. Equivalence a -> a -> a -> Bool
getEquivalence Equivalence a
eq a
key a
x)
breakPartition :: Equivalence a -> a -> AssocList a b
-> (AssocList a b, [b], AssocList a b)
breakPartition :: Equivalence a
-> a -> AssocList a b -> (AssocList a b, [b], AssocList a b)
breakPartition Equivalence a
eq a
key AssocList a b
l =
let
(AssocList a b
before, AssocList a b
l') = Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
forall a b.
Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
break Equivalence a
eq a
key AssocList a b
l
([b]
xs, AssocList a b
after) = Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
forall a b.
Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
partition Equivalence a
eq a
key AssocList a b
l'
in
(AssocList a b
before, [b]
xs, AssocList a b
after)
mapFirst :: Equivalence a -> a -> (b -> b) -> AssocList a b -> AssocList a b
mapFirst :: Equivalence a -> a -> (b -> b) -> AssocList a b -> AssocList a b
mapFirst Equivalence a
eq a
key b -> b
f AssocList a b
l =
let
(AssocList a b
before, AssocList a b
l') = Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
forall a b.
Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
break Equivalence a
eq a
key AssocList a b
l
in
AssocList a b
before AssocList a b -> AssocList a b -> AssocList a b
forall a. [a] -> [a] -> [a]
++
case AssocList a b
l' of
[] -> AssocList a b
l'
(a
x, b
y) : AssocList a b
after -> (a
x, b -> b
f b
y) (a, b) -> AssocList a b -> AssocList a b
forall a. a -> [a] -> [a]
: AssocList a b
after
mapAll :: Equivalence a -> a -> (b -> b) -> AssocList a b -> AssocList a b
mapAll :: Equivalence a -> a -> (b -> b) -> AssocList a b -> AssocList a b
mapAll Equivalence a
eq a
key b -> b
f =
((a, b) -> (a, b)) -> AssocList a b -> AssocList a b
forall a b. (a -> b) -> [a] -> [b]
Data.List.map (a, b) -> (a, b)
g
where
g :: (a, b) -> (a, b)
g xy :: (a, b)
xy@(a
x, b
y)
| Equivalence a -> a -> a -> Bool
forall a. Equivalence a -> a -> a -> Bool
getEquivalence Equivalence a
eq a
key a
x = (a
x, b -> b
f b
y)
| Bool
otherwise = (a, b)
xy
alterFirst :: Equivalence a -> a -> (Maybe b -> Maybe b)
-> AssocList a b -> AssocList a b
alterFirst :: Equivalence a
-> a -> (Maybe b -> Maybe b) -> AssocList a b -> AssocList a b
alterFirst Equivalence a
eq a
key Maybe b -> Maybe b
f AssocList a b
l =
let (AssocList a b
before, AssocList a b
l') = Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
forall a b.
Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
break Equivalence a
eq a
key AssocList a b
l
in AssocList a b
before AssocList a b -> AssocList a b -> AssocList a b
forall a. [a] -> [a] -> [a]
++ case AssocList a b
l' of
[] -> Maybe (a, b) -> AssocList a b
forall a. Maybe a -> [a]
maybeToList ((,) a
key (b -> (a, b)) -> Maybe b -> Maybe (a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe b -> Maybe b
f Maybe b
forall a. Maybe a
Nothing)
(a
x, b
y) : AssocList a b
after -> Maybe (a, b) -> AssocList a b
forall a. Maybe a -> [a]
maybeToList ((,) a
x (b -> (a, b)) -> Maybe b -> Maybe (a, b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe b -> Maybe b
f (b -> Maybe b
forall a. a -> Maybe a
Just b
y))
AssocList a b -> AssocList a b -> AssocList a b
forall a. [a] -> [a] -> [a]
++ AssocList a b
after
alterAll :: Equivalence a -> a -> ([b] -> [b])
-> AssocList a b -> AssocList a b
alterAll :: Equivalence a
-> a -> ([b] -> [b]) -> AssocList a b -> AssocList a b
alterAll Equivalence a
eq a
key [b] -> [b]
f AssocList a b
l =
let (AssocList a b
before, AssocList a b
l') = Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
forall a b.
Equivalence a
-> a -> AssocList a b -> (AssocList a b, AssocList a b)
break Equivalence a
eq a
key AssocList a b
l
in AssocList a b
before AssocList a b -> AssocList a b -> AssocList a b
forall a. [a] -> [a] -> [a]
++ case AssocList a b
l' of
[] -> (,) a
key (b -> (a, b)) -> [b] -> AssocList a b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [b] -> [b]
f []
AssocList a b
_ -> let ([b]
ys, AssocList a b
after) = Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
forall a b.
Equivalence a -> a -> AssocList a b -> ([b], AssocList a b)
partition Equivalence a
eq a
key AssocList a b
l'
in ((,) a
key (b -> (a, b)) -> [b] -> AssocList a b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [b] -> [b]
f [b]
ys) AssocList a b -> AssocList a b -> AssocList a b
forall a. [a] -> [a] -> [a]
++ AssocList a b
after