{-# LANGUAGE UndecidableInstances #-}
module Data.List.ApplyMerge (applyMerge, applyMergeBy, applyMergeOn) where
import ApplyMerge.IntSet qualified
import Data.Proxy (Proxy (..))
import Data.Reflection (Reifies, reflect, reify)
import Data.Semigroup (Arg (..))
applyMerge :: (Ord c) => (a -> b -> c) -> [a] -> [b] -> [c]
applyMerge :: forall c a b. Ord c => (a -> b -> c) -> [a] -> [b] -> [c]
applyMerge = (a -> b -> c) -> [a] -> [b] -> [c]
forall c a b. Ord c => (a -> b -> c) -> [a] -> [b] -> [c]
ApplyMerge.IntSet.applyMerge
applyMergeBy :: (c -> c -> Ordering) -> (a -> b -> c) -> [a] -> [b] -> [c]
applyMergeBy :: forall c a b.
(c -> c -> Ordering) -> (a -> b -> c) -> [a] -> [b] -> [c]
applyMergeBy = (c -> c -> Ordering) -> (a -> b -> c) -> [a] -> [b] -> [c]
forall a b c.
(c -> c -> Ordering) -> (a -> b -> c) -> [a] -> [b] -> [c]
applyMergeBy_
applyMergeBy_ ::
forall a b c. (c -> c -> Ordering) -> (a -> b -> c) -> [a] -> [b] -> [c]
applyMergeBy_ :: forall a b c.
(c -> c -> Ordering) -> (a -> b -> c) -> [a] -> [b] -> [c]
applyMergeBy_ c -> c -> Ordering
cmp a -> b -> c
f [a]
as [b]
bs =
(c -> c -> Ordering)
-> (forall {s}. Reifies s (c -> c -> Ordering) => Proxy s -> [c])
-> [c]
forall a r. a -> (forall s. Reifies s a => Proxy s -> r) -> r
reify c -> c -> Ordering
cmp ((forall {s}. Reifies s (c -> c -> Ordering) => Proxy s -> [c])
-> [c])
-> (forall {s}. Reifies s (c -> c -> Ordering) => Proxy s -> [c])
-> [c]
forall a b. (a -> b) -> a -> b
$ \(Proxy s
_ :: Proxy s) ->
let f' :: a -> b -> ReflectedOrd s c
f' :: a -> b -> ReflectedOrd s c
f' a
a b
b = c -> ReflectedOrd s c
forall {k} (s :: k) a. a -> ReflectedOrd s a
ReflectedOrd (a -> b -> c
f a
a b
b)
in (ReflectedOrd s c -> c) -> [ReflectedOrd s c] -> [c]
forall a b. (a -> b) -> [a] -> [b]
map ReflectedOrd s c -> c
forall {k} (s :: k) a. ReflectedOrd s a -> a
unReflectedOrd ((a -> b -> ReflectedOrd s c) -> [a] -> [b] -> [ReflectedOrd s c]
forall c a b. Ord c => (a -> b -> c) -> [a] -> [b] -> [c]
applyMerge a -> b -> ReflectedOrd s c
f' [a]
as [b]
bs)
newtype ReflectedOrd s a = ReflectedOrd {forall {k} (s :: k) a. ReflectedOrd s a -> a
unReflectedOrd :: a}
instance (Reifies s (a -> a -> Ordering)) => Eq (ReflectedOrd s a) where
== :: ReflectedOrd s a -> ReflectedOrd s a -> Bool
(==) (ReflectedOrd a
x) (ReflectedOrd a
y) =
let cmp :: a -> a -> Ordering
cmp = Proxy s -> a -> a -> Ordering
forall {k} (s :: k) a (proxy :: k -> *).
Reifies s a =>
proxy s -> a
forall (proxy :: k -> *). proxy s -> a -> a -> Ordering
reflect (Proxy s
forall {k} (t :: k). Proxy t
Proxy :: Proxy s)
in a -> a -> Ordering
cmp a
x a
y Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ
instance (Reifies s (a -> a -> Ordering)) => Ord (ReflectedOrd s a) where
compare :: ReflectedOrd s a -> ReflectedOrd s a -> Ordering
compare (ReflectedOrd a
x) (ReflectedOrd a
y) =
let cmp :: a -> a -> Ordering
cmp = Proxy s -> a -> a -> Ordering
forall {k} (s :: k) a (proxy :: k -> *).
Reifies s a =>
proxy s -> a
forall (proxy :: k -> *). proxy s -> a -> a -> Ordering
reflect (Proxy s
forall {k} (t :: k). Proxy t
Proxy :: Proxy s)
in a -> a -> Ordering
cmp a
x a
y
applyMergeOn ::
(Ord d) => (c -> d) -> (a -> b -> c) -> [a] -> [b] -> [c]
applyMergeOn :: forall d c a b.
Ord d =>
(c -> d) -> (a -> b -> c) -> [a] -> [b] -> [c]
applyMergeOn c -> d
p a -> b -> c
f [a]
as [b]
bs =
let f' :: a -> b -> Arg d c
f' a
a b
b =
let c :: c
c = a -> b -> c
f a
a b
b
in d -> c -> Arg d c
forall a b. a -> b -> Arg a b
Arg (c -> d
p c
c) c
c
in (Arg d c -> c) -> [Arg d c] -> [c]
forall a b. (a -> b) -> [a] -> [b]
map (\(Arg d
_ c
c) -> c
c) ((a -> b -> Arg d c) -> [a] -> [b] -> [Arg d c]
forall c a b. Ord c => (a -> b -> c) -> [a] -> [b] -> [c]
applyMerge a -> b -> Arg d c
f' [a]
as [b]
bs)