{-# LANGUAGE FlexibleContexts, ScopedTypeVariables, ViewPatterns #-}
module Data.AssocList.ListLike.Predicate
(
lookupFirst
, lookupAll
, removeFirst
, removeAll
, mapFirst
, mapAll
, partition
, break
, breakPartition
) where
import Data.AssocList.ListLike.Concept
import Control.Exception (throw)
import Prelude (Eq (..), Maybe (..), maybe, error, otherwise, (<$>))
import Data.ListLike (cons, uncons)
import qualified Data.ListLike as LL
import Data.Functor.Contravariant (Predicate (..))
lookupFirst :: forall l a b. AssocList l a b
=> Predicate a -> l -> Maybe b
lookupFirst :: Predicate a -> l -> Maybe b
lookupFirst Predicate a
_key (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Maybe ((a, b), l)
Nothing) = Maybe b
forall a. Maybe a
Nothing
lookupFirst Predicate a
key (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Just ((a
x, b
y), l
xys))
| Predicate a -> a -> Bool
forall a. Predicate a -> a -> Bool
getPredicate Predicate a
key a
x = b -> Maybe b
forall a. a -> Maybe a
Just b
y
| Bool
otherwise = Predicate a -> l -> Maybe b
forall l a b. AssocList l a b => Predicate a -> l -> Maybe b
lookupFirst Predicate a
key l
xys
lookupAll :: forall l a b. AssocList l a b
=> Predicate a -> l -> [b]
lookupAll :: Predicate a -> l -> [b]
lookupAll Predicate a
_key (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Maybe ((a, b), l)
Nothing) = []
lookupAll Predicate a
key (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Just ((a
x, b
y), l
xys))
| Predicate a -> a -> Bool
forall a. Predicate a -> a -> Bool
getPredicate Predicate a
key a
x = b
y b -> [b] -> [b]
forall a. a -> [a] -> [a]
: Predicate a -> l -> [b]
forall l a b. AssocList l a b => Predicate a -> l -> [b]
lookupAll Predicate a
key l
xys
| Bool
otherwise = Predicate a -> l -> [b]
forall l a b. AssocList l a b => Predicate a -> l -> [b]
lookupAll Predicate a
key l
xys
removeFirst :: forall l a b. AssocList l a b
=> Predicate a -> l -> l
removeFirst :: Predicate a -> l -> l
removeFirst Predicate a
_key l :: l
l@(l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Maybe ((a, b), l)
Nothing) = l
l
removeFirst Predicate a
key (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Just (xy :: (a, b)
xy@(a
x, b
y), l
xys))
| Predicate a -> a -> Bool
forall a. Predicate a -> a -> Bool
getPredicate Predicate a
key a
x = l
xys
| Bool
otherwise = (a, b) -> l -> l
forall full item. ListLike full item => item -> full -> full
cons (a, b)
xy (Predicate a -> l -> l
forall l a b. AssocList l a b => Predicate a -> l -> l
removeFirst Predicate a
key l
xys)
removeAll :: forall l a b. AssocList l a b
=> Predicate a -> l -> l
removeAll :: Predicate a -> l -> l
removeAll Predicate a
_key l :: l
l@(l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Maybe ((a, b), l)
Nothing) = l
l
removeAll Predicate a
key (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Just (xy :: (a, b)
xy@(a
x, b
y), l
xys))
| Predicate a -> a -> Bool
forall a. Predicate a -> a -> Bool
getPredicate Predicate a
key a
x = Predicate a -> l -> l
forall l a b. AssocList l a b => Predicate a -> l -> l
removeAll Predicate a
key l
xys
| Bool
otherwise = (a, b) -> l -> l
forall full item. ListLike full item => item -> full -> full
cons (a, b)
xy (Predicate a -> l -> l
forall l a b. AssocList l a b => Predicate a -> l -> l
removeAll Predicate a
key l
xys)
partition :: forall l a b. AssocList l a b
=> Predicate a -> l -> ([b], l)
partition :: Predicate a -> l -> ([b], l)
partition Predicate a
_key l :: l
l@(l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Maybe ((a, b), l)
Nothing) = ([], l
l)
partition Predicate a
key (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons -> Just (xy :: (a, b)
xy@(a
x, b
y), l
xys))
| Predicate a -> a -> Bool
forall a. Predicate a -> a -> Bool
getPredicate Predicate a
key a
x = (b
y b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b]
yes , l
no)
| Bool
otherwise = ( [b]
yes , (a, b) -> l -> l
forall full item. ListLike full item => item -> full -> full
cons (a, b)
xy l
no)
where
([b]
yes, l
no) = Predicate a -> l -> ([b], l)
forall l a b. AssocList l a b => Predicate a -> l -> ([b], l)
partition Predicate a
key l
xys
break :: forall l a b. AssocList l a b
=> Predicate a -> l -> (l, l)
break :: Predicate a -> l -> (l, l)
break Predicate a
key = ((a, b) -> Bool) -> l -> (l, l)
forall full item.
ListLike full item =>
(item -> Bool) -> full -> (full, full)
LL.break (\(a
x, b
y) -> Predicate a -> a -> Bool
forall a. Predicate a -> a -> Bool
getPredicate Predicate a
key a
x)
breakPartition :: forall l a b. AssocList l a b
=> Predicate a -> l -> (l, [b], l)
breakPartition :: Predicate a -> l -> (l, [b], l)
breakPartition Predicate a
key l
l =
let
(l
before, l
l') = Predicate a -> l -> (l, l)
forall l a b. AssocList l a b => Predicate a -> l -> (l, l)
break Predicate a
key l
l
([b]
xs, l
after) = Predicate a -> l -> ([b], l)
forall l a b. AssocList l a b => Predicate a -> l -> ([b], l)
partition Predicate a
key l
l'
in
(l
before, [b]
xs, l
after)
mapFirst :: forall l a b. AssocList l a b
=> Predicate a -> (b -> b) -> l -> l
mapFirst :: Predicate a -> (b -> b) -> l -> l
mapFirst Predicate a
key b -> b
f l
l =
let
(l
before, l
l') = Predicate a -> l -> (l, l)
forall l a b. AssocList l a b => Predicate a -> l -> (l, l)
break Predicate a
key l
l
in
l
before l -> l -> l
forall full item. ListLike full item => full -> full -> full
`LL.append`
case (l -> Maybe ((a, b), l)
forall full item. ListLike full item => full -> Maybe (item, full)
uncons l
l') of
Maybe ((a, b), l)
Nothing -> l
l'
Just ((a
x, b
y), l
after) -> (a, b) -> l -> l
forall full item. ListLike full item => item -> full -> full
cons (a
x, b -> b
f b
y) l
after
mapAll :: forall l a b. AssocList l a b
=> Predicate a -> (b -> b) -> l -> l
mapAll :: Predicate a -> (b -> b) -> l -> l
mapAll Predicate a
key b -> b
f =
((a, b) -> (a, b)) -> l -> l
forall full item full' item'.
(ListLike full item, ListLike full' item') =>
(item -> item') -> full -> full'
LL.map (a, b) -> (a, b)
g
where
g :: (a, b) -> (a, b)
g xy :: (a, b)
xy@(a
x, b
y)
| Predicate a -> a -> Bool
forall a. Predicate a -> a -> Bool
getPredicate Predicate a
key a
x = (a
x, b -> b
f b
y)
| Bool
otherwise = (a, b)
xy