module Data.Type.Witness.Specific.OrderedWitnessMap.Of where

import Data.Type.Witness.General.Order
import Data.Type.Witness.Specific.OrderedWitnessMap.For
import Data.Type.Witness.Specific.Some
import Import

-- | A dictionary that is heterogenous up to its simple witness type @w@.
-- Witnesses are the keys of the dictionary, and the values they witness are the values of the dictionary.
type OrderedWitnessMapOf :: (Type -> Type) -> Type
type OrderedWitnessMapOf = OrderedWitnessMapFor Identity

-- | An empty dictionary.
emptyOrderedWitnessMapOf :: TestOrder w => OrderedWitnessMapOf w
emptyOrderedWitnessMapOf :: forall (w :: Type -> Type). TestOrder w => OrderedWitnessMapOf w
emptyOrderedWitnessMapOf = OrderedWitnessMapFor Identity w
forall {k} (w :: k -> Type) (f :: k -> Type).
TestOrder w =>
OrderedWitnessMapFor f w
emptyOrderedWitnessMapFor

-- | Look up the first value in the dictionary that matches the given witness.
orderedWitnessMapOfLookup :: TestOrder w => w a -> OrderedWitnessMapOf w -> Maybe a
orderedWitnessMapOfLookup :: forall (w :: Type -> Type) a.
TestOrder w =>
w a -> OrderedWitnessMapOf w -> Maybe a
orderedWitnessMapOfLookup w a
wit OrderedWitnessMapOf w
d = (Identity a -> a) -> Maybe (Identity a) -> Maybe a
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Identity a -> a
forall a. Identity a -> a
runIdentity (Maybe (Identity a) -> Maybe a) -> Maybe (Identity a) -> Maybe a
forall a b. (a -> b) -> a -> b
$ w a -> OrderedWitnessMapOf w -> Maybe (Identity a)
forall {k} (w :: k -> Type) (a :: k) (f :: k -> Type).
TestOrder w =>
w a -> OrderedWitnessMapFor f w -> Maybe (f a)
orderedWitnessMapForLookup w a
wit OrderedWitnessMapOf w
d

-- | Modify the first value in the dictionary that matches a particular witness.
orderedWitnessMapOfModify :: TestOrder w => w a -> (a -> a) -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfModify :: forall (w :: Type -> Type) a.
TestOrder w =>
w a -> (a -> a) -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfModify w a
wit a -> a
amap = w a
-> (Identity a -> Identity a)
-> OrderedWitnessMapFor Identity w
-> OrderedWitnessMapFor Identity w
forall {k} (f :: k -> Type) (w :: k -> Type) (a :: k).
TestOrder w =>
w a
-> (f a -> f a)
-> OrderedWitnessMapFor f w
-> OrderedWitnessMapFor f w
orderedWitnessMapForModify w a
wit (a -> Identity a
forall a. a -> Identity a
Identity (a -> Identity a) -> (Identity a -> a) -> Identity a -> Identity a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> a
amap (a -> a) -> (Identity a -> a) -> Identity a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> Type) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Identity a -> a
forall a. Identity a -> a
runIdentity)

-- | Replace the first value in the dictionary that matches the witness
orderedWitnessMapOfReplace :: TestOrder w => w a -> a -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfReplace :: forall (w :: Type -> Type) a.
TestOrder w =>
w a -> a -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfReplace w a
wit a
newa = w a -> (a -> a) -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
forall (w :: Type -> Type) a.
TestOrder w =>
w a -> (a -> a) -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfModify w a
wit ((a -> a) -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w)
-> (a -> a) -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
forall a b. (a -> b) -> a -> b
$ a -> a -> a
forall a b. a -> b -> a
const a
newa

orderedWitnessMapOfSingle :: w a -> a -> OrderedWitnessMapOf w
orderedWitnessMapOfSingle :: forall (w :: Type -> Type) a. w a -> a -> OrderedWitnessMapOf w
orderedWitnessMapOfSingle w a
wit a
a = w a -> Identity a -> OrderedWitnessMapFor Identity w
forall {k} (w :: k -> Type) (a :: k) (f :: k -> Type).
w a -> f a -> OrderedWitnessMapFor f w
orderedWitnessMapForSingle w a
wit (Identity a -> OrderedWitnessMapFor Identity w)
-> Identity a -> OrderedWitnessMapFor Identity w
forall a b. (a -> b) -> a -> b
$ a -> Identity a
forall a. a -> Identity a
Identity a
a

orderedWitnessMapOfFold :: Monoid m => OrderedWitnessMapOf w -> (forall a. w a -> a -> m) -> m
orderedWitnessMapOfFold :: forall m (w :: Type -> Type).
Monoid m =>
OrderedWitnessMapOf w -> (forall a. w a -> a -> m) -> m
orderedWitnessMapOfFold OrderedWitnessMapOf w
d forall a. w a -> a -> m
f = OrderedWitnessMapOf w -> (forall {a}. w a -> Identity a -> m) -> m
forall {k} m (f :: k -> Type) (w :: k -> Type).
Monoid m =>
OrderedWitnessMapFor f w -> (forall (a :: k). w a -> f a -> m) -> m
orderedWitnessMapForFold OrderedWitnessMapOf w
d ((forall {a}. w a -> Identity a -> m) -> m)
-> (forall {a}. w a -> Identity a -> m) -> m
forall a b. (a -> b) -> a -> b
$ \w a
wa (Identity a
a) -> w a -> a -> m
forall a. w a -> a -> m
f w a
wa a
a

-- | Add a witness and value as the first entry in the dictionary.
orderedWitnessMapOfAdd :: TestOrder w => w a -> a -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfAdd :: forall (w :: Type -> Type) a.
TestOrder w =>
w a -> a -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfAdd w a
wit a
a = w a
-> Identity a
-> OrderedWitnessMapFor Identity w
-> OrderedWitnessMapFor Identity w
forall {k} (w :: k -> Type) (a :: k) (f :: k -> Type).
TestOrder w =>
w a -> f a -> OrderedWitnessMapFor f w -> OrderedWitnessMapFor f w
orderedWitnessMapForAdd w a
wit (Identity a
 -> OrderedWitnessMapFor Identity w
 -> OrderedWitnessMapFor Identity w)
-> Identity a
-> OrderedWitnessMapFor Identity w
-> OrderedWitnessMapFor Identity w
forall a b. (a -> b) -> a -> b
$ a -> Identity a
forall a. a -> Identity a
Identity a
a

-- | Remove the first entry in the dictionary that matches the given witness.
orderedWitnessMapOfRemove :: TestOrder w => w a -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfRemove :: forall (w :: Type -> Type) a.
TestOrder w =>
w a -> OrderedWitnessMapOf w -> OrderedWitnessMapOf w
orderedWitnessMapOfRemove = w a
-> OrderedWitnessMapFor Identity w
-> OrderedWitnessMapFor Identity w
forall {k} (w :: k -> Type) (a :: k) (f :: k -> Type).
TestOrder w =>
w a -> OrderedWitnessMapFor f w -> OrderedWitnessMapFor f w
orderedWitnessMapForRemove

-- | Create a dictionary from a list of witness\/value pairs
orderedWitnessMapOfFromList :: TestOrder w => [SomeOf w] -> OrderedWitnessMapOf w
orderedWitnessMapOfFromList :: forall (w :: Type -> Type).
TestOrder w =>
[SomeOf w] -> OrderedWitnessMapOf w
orderedWitnessMapOfFromList = [SomeFor Identity w] -> OrderedWitnessMapFor Identity w
forall {k} (w :: k -> Type) (f :: k -> Type).
TestOrder w =>
[SomeFor f w] -> OrderedWitnessMapFor f w
orderedWitnessMapForFromList

orderedWitnessMapOfToList :: OrderedWitnessMapOf w -> [SomeOf w]
orderedWitnessMapOfToList :: forall (w :: Type -> Type). OrderedWitnessMapOf w -> [SomeOf w]
orderedWitnessMapOfToList = OrderedWitnessMapFor Identity w -> [SomeFor Identity w]
forall {k} (f :: k -> Type) (w :: k -> Type).
OrderedWitnessMapFor f w -> [SomeFor f w]
orderedWitnessMapForToList