{-# LANGUAGE DeriveFunctor #-}
module Data.TreeDiff.OMap (
OMap,
toAscList,
toList,
fromList,
empty,
elems,
) where
import Control.DeepSeq (NFData (..))
import Data.List (sortBy)
import Data.Ord (comparing)
import Data.Semialign (Semialign (..))
import Data.These (These (..))
import qualified Data.Map.Strict as Map
import qualified Test.QuickCheck as QC
newtype OMap k v = OMap (Map.Map k (Val v))
deriving ((forall a b. (a -> b) -> OMap k a -> OMap k b)
-> (forall a b. a -> OMap k b -> OMap k a) -> Functor (OMap k)
forall a b. a -> OMap k b -> OMap k a
forall a b. (a -> b) -> OMap k a -> OMap k b
forall k a b. a -> OMap k b -> OMap k a
forall k a b. (a -> b) -> OMap k a -> OMap k b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall k a b. (a -> b) -> OMap k a -> OMap k b
fmap :: forall a b. (a -> b) -> OMap k a -> OMap k b
$c<$ :: forall k a b. a -> OMap k b -> OMap k a
<$ :: forall a b. a -> OMap k b -> OMap k a
Functor)
data Val v = Val !Int v
deriving ((forall a b. (a -> b) -> Val a -> Val b)
-> (forall a b. a -> Val b -> Val a) -> Functor Val
forall a b. a -> Val b -> Val a
forall a b. (a -> b) -> Val a -> Val b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Val a -> Val b
fmap :: forall a b. (a -> b) -> Val a -> Val b
$c<$ :: forall a b. a -> Val b -> Val a
<$ :: forall a b. a -> Val b -> Val a
Functor)
instance (Show k, Show v) => Show (OMap k v) where
showsPrec :: Int -> OMap k v -> ShowS
showsPrec Int
d OMap k v
m = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
10)
(ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ String -> ShowS
showString String
"fromList "
ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [(k, v)] -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
d (OMap k v -> [(k, v)]
forall k v. OMap k v -> [(k, v)]
toList OMap k v
m)
instance (Eq k, Eq v) => Eq (OMap k v) where
OMap k v
xs == :: OMap k v -> OMap k v -> Bool
== OMap k v
ys = OMap k v -> [(k, v)]
forall k v. OMap k v -> [(k, v)]
toAscList OMap k v
xs [(k, v)] -> [(k, v)] -> Bool
forall a. Eq a => a -> a -> Bool
== OMap k v -> [(k, v)]
forall k v. OMap k v -> [(k, v)]
toAscList OMap k v
ys
instance (Ord k, Ord v) => Ord (OMap k v) where
compare :: OMap k v -> OMap k v -> Ordering
compare OMap k v
xs OMap k v
ys = [(k, v)] -> [(k, v)] -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (OMap k v -> [(k, v)]
forall k v. OMap k v -> [(k, v)]
toAscList OMap k v
xs) (OMap k v -> [(k, v)]
forall k v. OMap k v -> [(k, v)]
toAscList OMap k v
ys)
instance NFData v => NFData (Val v) where
rnf :: Val v -> ()
rnf (Val Int
_ v
v) = v -> ()
forall a. NFData a => a -> ()
rnf v
v
instance (NFData k, NFData v) => NFData (OMap k v) where
rnf :: OMap k v -> ()
rnf (OMap Map k (Val v)
m) = Map k (Val v) -> ()
forall a. NFData a => a -> ()
rnf Map k (Val v)
m
instance (Ord k, QC.Arbitrary k, QC.Arbitrary v) => QC.Arbitrary (OMap k v) where
arbitrary :: Gen (OMap k v)
arbitrary = Gen (OMap k v)
forall (f :: * -> *) a. (Arbitrary1 f, Arbitrary a) => Gen (f a)
QC.arbitrary1
shrink :: OMap k v -> [OMap k v]
shrink = OMap k v -> [OMap k v]
forall (f :: * -> *) a. (Arbitrary1 f, Arbitrary a) => f a -> [f a]
QC.shrink1
instance (Ord k, QC.Arbitrary k) => QC.Arbitrary1 (OMap k) where
liftArbitrary :: forall a. Gen a -> Gen (OMap k a)
liftArbitrary Gen a
arb = ([(k, a)] -> OMap k a) -> Gen [(k, a)] -> Gen (OMap k a)
forall a b. (a -> b) -> Gen a -> Gen b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(k, a)] -> OMap k a
forall k v. Ord k => [(k, v)] -> OMap k v
fromList (Gen [(k, a)] -> Gen (OMap k a)) -> Gen [(k, a)] -> Gen (OMap k a)
forall a b. (a -> b) -> a -> b
$ Gen (k, a) -> Gen [(k, a)]
forall a. Gen a -> Gen [a]
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
QC.liftArbitrary (Gen a -> Gen (k, a)
forall a. Gen a -> Gen (k, a)
forall (f :: * -> *) a. Arbitrary1 f => Gen a -> Gen (f a)
QC.liftArbitrary Gen a
arb)
liftShrink :: forall a. (a -> [a]) -> OMap k a -> [OMap k a]
liftShrink a -> [a]
shr OMap k a
m = ([(k, a)] -> OMap k a) -> [[(k, a)]] -> [OMap k a]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(k, a)] -> OMap k a
forall k v. Ord k => [(k, v)] -> OMap k v
fromList ([[(k, a)]] -> [OMap k a]) -> [[(k, a)]] -> [OMap k a]
forall a b. (a -> b) -> a -> b
$ ((k, a) -> [(k, a)]) -> [(k, a)] -> [[(k, a)]]
forall a. (a -> [a]) -> [a] -> [[a]]
forall (f :: * -> *) a. Arbitrary1 f => (a -> [a]) -> f a -> [f a]
QC.liftShrink ((a -> [a]) -> (k, a) -> [(k, a)]
forall a. (a -> [a]) -> (k, a) -> [(k, a)]
forall (f :: * -> *) a. Arbitrary1 f => (a -> [a]) -> f a -> [f a]
QC.liftShrink a -> [a]
shr) ([(k, a)] -> [[(k, a)]]) -> [(k, a)] -> [[(k, a)]]
forall a b. (a -> b) -> a -> b
$ OMap k a -> [(k, a)]
forall k v. OMap k v -> [(k, v)]
toList OMap k a
m
empty :: OMap k v
empty :: forall k v. OMap k v
empty = Map k (Val v) -> OMap k v
forall k v. Map k (Val v) -> OMap k v
OMap Map k (Val v)
forall k a. Map k a
Map.empty
elems :: OMap k v -> [v]
elems :: forall k v. OMap k v -> [v]
elems (OMap Map k (Val v)
m) = ((k, Val v) -> v) -> [(k, Val v)] -> [v]
forall a b. (a -> b) -> [a] -> [b]
map ((k, v) -> v
forall a b. (a, b) -> b
snd ((k, v) -> v) -> ((k, Val v) -> (k, v)) -> (k, Val v) -> v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k, Val v) -> (k, v)
forall k v. (k, Val v) -> (k, v)
getVal) ([(k, Val v)] -> [v]) -> [(k, Val v)] -> [v]
forall a b. (a -> b) -> a -> b
$ Map k (Val v) -> [(k, Val v)]
forall k a. Map k a -> [(k, a)]
Map.toAscList Map k (Val v)
m
toAscList :: OMap k v -> [(k, v)]
toAscList :: forall k v. OMap k v -> [(k, v)]
toAscList (OMap Map k (Val v)
m) = ((k, Val v) -> (k, v)) -> [(k, Val v)] -> [(k, v)]
forall a b. (a -> b) -> [a] -> [b]
map (k, Val v) -> (k, v)
forall k v. (k, Val v) -> (k, v)
getVal ([(k, Val v)] -> [(k, v)]) -> [(k, Val v)] -> [(k, v)]
forall a b. (a -> b) -> a -> b
$ Map k (Val v) -> [(k, Val v)]
forall k a. Map k a -> [(k, a)]
Map.toAscList Map k (Val v)
m
toList :: OMap k v -> [(k, v)]
toList :: forall k v. OMap k v -> [(k, v)]
toList (OMap Map k (Val v)
m) = ((k, Val v) -> (k, v)) -> [(k, Val v)] -> [(k, v)]
forall a b. (a -> b) -> [a] -> [b]
map (k, Val v) -> (k, v)
forall k v. (k, Val v) -> (k, v)
getVal ([(k, Val v)] -> [(k, v)]) -> [(k, Val v)] -> [(k, v)]
forall a b. (a -> b) -> a -> b
$ ((k, Val v) -> (k, Val v) -> Ordering)
-> [(k, Val v)] -> [(k, Val v)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy (((k, Val v) -> Int) -> (k, Val v) -> (k, Val v) -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (k, Val v) -> Int
forall k v. (k, Val v) -> Int
getIdx) ([(k, Val v)] -> [(k, Val v)]) -> [(k, Val v)] -> [(k, Val v)]
forall a b. (a -> b) -> a -> b
$ Map k (Val v) -> [(k, Val v)]
forall k a. Map k a -> [(k, a)]
Map.toList Map k (Val v)
m
getIdx :: (k, Val v) -> Int
getIdx :: forall k v. (k, Val v) -> Int
getIdx (k
_, Val Int
i v
_) = Int
i
getVal :: (k, Val v) -> (k, v)
getVal :: forall k v. (k, Val v) -> (k, v)
getVal (k
k, Val Int
_ v
v) = (k
k, v
v)
fromList :: Ord k => [(k, v)] -> OMap k v
fromList :: forall k v. Ord k => [(k, v)] -> OMap k v
fromList [(k, v)]
kvs = Map k (Val v) -> OMap k v
forall k v. Map k (Val v) -> OMap k v
OMap ([(k, Val v)] -> Map k (Val v)
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ((Int -> (k, v) -> (k, Val v)) -> [Int] -> [(k, v)] -> [(k, Val v)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> (k, v) -> (k, Val v)
forall {a} {v}. Int -> (a, v) -> (a, Val v)
p [Int
0..] [(k, v)]
kvs)) where
p :: Int -> (a, v) -> (a, Val v)
p Int
i (a
k, v
v) = (a
k, Int -> v -> Val v
forall v. Int -> v -> Val v
Val Int
i v
v)
instance Ord k => Semialign (OMap k) where
alignWith :: forall a b c. (These a b -> c) -> OMap k a -> OMap k b -> OMap k c
alignWith These a b -> c
f (OMap Map k (Val a)
xs) (OMap Map k (Val b)
ys) = Map k (Val c) -> OMap k c
forall k v. Map k (Val v) -> OMap k v
OMap ((These (Val a) (Val b) -> Val c)
-> Map k (Val a) -> Map k (Val b) -> Map k (Val c)
forall a b c. (These a b -> c) -> Map k a -> Map k b -> Map k c
forall (f :: * -> *) a b c.
Semialign f =>
(These a b -> c) -> f a -> f b -> f c
alignWith These (Val a) (Val b) -> Val c
g Map k (Val a)
xs Map k (Val b)
ys) where
g :: These (Val a) (Val b) -> Val c
g (This (Val Int
i a
x)) = Int -> c -> Val c
forall v. Int -> v -> Val v
Val Int
i (These a b -> c
f (a -> These a b
forall a b. a -> These a b
This a
x))
g (That (Val Int
j b
y)) = Int -> c -> Val c
forall v. Int -> v -> Val v
Val Int
j (These a b -> c
f (b -> These a b
forall a b. b -> These a b
That b
y))
g (These (Val Int
i a
x) (Val Int
j b
y)) = Int -> c -> Val c
forall v. Int -> v -> Val v
Val (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
i Int
j) (These a b -> c
f (a -> b -> These a b
forall a b. a -> b -> These a b
These a
x b
y))