{-# LANGUAGE RoleAnnotations #-}

-- |
-- Copyright: © 2022–2026 Jonathan Knowles
-- License: Apache-2.0
--
-- Defines the 'NonNullMap' type, together with the primitive operations on
-- 'NonNullMap' that need access to the data constructor of 'NonNull'.
--
module Data.MonoidMap.Internal.NonNullMap.Unsafe
    ( NonNullMap (..)
    , toMap
    , unsafeFromMap
    )
    where

import Prelude

import Control.DeepSeq
    ( NFData )
import Data.Bifoldable
    ( Bifoldable )
import Data.Coerce
    ( coerce )
import Data.Functor.Classes
    ( Eq1, Eq2, Show1, Show2 )
import Data.Map.Strict
    ( Map )
import Data.MonoidMap.Internal.NonNull.Unsafe
    ( NonNull (UnsafeNonNull) )

-- | A map of 'NonNull' values.
--
-- Other types with the same representation (such as @MonoidMap@ from the
-- @monoidmap@ package) can derive instances via this type, without access
-- to the data constructor of 'NonNull'.
--
newtype NonNullMap k v = NonNullMap (Map k (NonNull v))
    --
    -- Here we take great care to only derive instances that consume values.
    --
    -- It's risky to derive an instance that produces values, as the derived
    -- instance may not necessarily respect the 'NonNull' invariant.
    --
    -- For example, the 'Read' instance for 'Map', given appropriate input,
    -- will quite happily produce maps with 'mempty' values.
    --
    deriving (NonNullMap k v -> NonNullMap k v -> Bool
(NonNullMap k v -> NonNullMap k v -> Bool)
-> (NonNullMap k v -> NonNullMap k v -> Bool)
-> Eq (NonNullMap k v)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall k v.
(Eq k, Eq v) =>
NonNullMap k v -> NonNullMap k v -> Bool
$c== :: forall k v.
(Eq k, Eq v) =>
NonNullMap k v -> NonNullMap k v -> Bool
== :: NonNullMap k v -> NonNullMap k v -> Bool
$c/= :: forall k v.
(Eq k, Eq v) =>
NonNullMap k v -> NonNullMap k v -> Bool
/= :: NonNullMap k v -> NonNullMap k v -> Bool
Eq, Int -> NonNullMap k v -> ShowS
[NonNullMap k v] -> ShowS
NonNullMap k v -> String
(Int -> NonNullMap k v -> ShowS)
-> (NonNullMap k v -> String)
-> ([NonNullMap k v] -> ShowS)
-> Show (NonNullMap k v)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall k v. (Show k, Show v) => Int -> NonNullMap k v -> ShowS
forall k v. (Show k, Show v) => [NonNullMap k v] -> ShowS
forall k v. (Show k, Show v) => NonNullMap k v -> String
$cshowsPrec :: forall k v. (Show k, Show v) => Int -> NonNullMap k v -> ShowS
showsPrec :: Int -> NonNullMap k v -> ShowS
$cshow :: forall k v. (Show k, Show v) => NonNullMap k v -> String
show :: NonNullMap k v -> String
$cshowList :: forall k v. (Show k, Show v) => [NonNullMap k v] -> ShowS
showList :: [NonNullMap k v] -> ShowS
Show, NonNullMap k v -> ()
(NonNullMap k v -> ()) -> NFData (NonNullMap k v)
forall a. (a -> ()) -> NFData a
forall k v. (NFData k, NFData v) => NonNullMap k v -> ()
$crnf :: forall k v. (NFData k, NFData v) => NonNullMap k v -> ()
rnf :: NonNullMap k v -> ()
NFData) via Map k v
    deriving ((forall a. Eq a => Eq (NonNullMap k a)) =>
(forall a b.
 (a -> b -> Bool) -> NonNullMap k a -> NonNullMap k b -> Bool)
-> Eq1 (NonNullMap k)
forall a. Eq a => Eq (NonNullMap k a)
forall k a. (Eq k, Eq a) => Eq (NonNullMap k a)
forall k a b.
Eq k =>
(a -> b -> Bool) -> NonNullMap k a -> NonNullMap k b -> Bool
forall a b.
(a -> b -> Bool) -> NonNullMap k a -> NonNullMap k b -> Bool
forall (f :: * -> *).
(forall a. Eq a => Eq (f a)) =>
(forall a b. (a -> b -> Bool) -> f a -> f b -> Bool) -> Eq1 f
$cliftEq :: forall k a b.
Eq k =>
(a -> b -> Bool) -> NonNullMap k a -> NonNullMap k b -> Bool
liftEq :: forall a b.
(a -> b -> Bool) -> NonNullMap k a -> NonNullMap k b -> Bool
Eq1, (forall a. Show a => Show (NonNullMap k a)) =>
(forall a.
 (Int -> a -> ShowS)
 -> ([a] -> ShowS) -> Int -> NonNullMap k a -> ShowS)
-> (forall a.
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> [NonNullMap k a] -> ShowS)
-> Show1 (NonNullMap k)
forall a. Show a => Show (NonNullMap k a)
forall k a. (Show k, Show a) => Show (NonNullMap k a)
forall k a.
Show k =>
(Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> NonNullMap k a -> ShowS
forall k a.
Show k =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [NonNullMap k a] -> ShowS
forall a.
(Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> NonNullMap k a -> ShowS
forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [NonNullMap k a] -> ShowS
forall (f :: * -> *).
(forall a. Show a => Show (f a)) =>
(forall a.
 (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> f a -> ShowS)
-> (forall a.
    (Int -> a -> ShowS) -> ([a] -> ShowS) -> [f a] -> ShowS)
-> Show1 f
$cliftShowsPrec :: forall k a.
Show k =>
(Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> NonNullMap k a -> ShowS
liftShowsPrec :: forall a.
(Int -> a -> ShowS)
-> ([a] -> ShowS) -> Int -> NonNullMap k a -> ShowS
$cliftShowList :: forall k a.
Show k =>
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [NonNullMap k a] -> ShowS
liftShowList :: forall a.
(Int -> a -> ShowS) -> ([a] -> ShowS) -> [NonNullMap k a] -> ShowS
Show1, (forall m. Monoid m => NonNullMap k m -> m)
-> (forall m a. Monoid m => (a -> m) -> NonNullMap k a -> m)
-> (forall m a. Monoid m => (a -> m) -> NonNullMap k a -> m)
-> (forall a b. (a -> b -> b) -> b -> NonNullMap k a -> b)
-> (forall a b. (a -> b -> b) -> b -> NonNullMap k a -> b)
-> (forall b a. (b -> a -> b) -> b -> NonNullMap k a -> b)
-> (forall b a. (b -> a -> b) -> b -> NonNullMap k a -> b)
-> (forall a. (a -> a -> a) -> NonNullMap k a -> a)
-> (forall a. (a -> a -> a) -> NonNullMap k a -> a)
-> (forall a. NonNullMap k a -> [a])
-> (forall a. NonNullMap k a -> Bool)
-> (forall a. NonNullMap k a -> Int)
-> (forall a. Eq a => a -> NonNullMap k a -> Bool)
-> (forall a. Ord a => NonNullMap k a -> a)
-> (forall a. Ord a => NonNullMap k a -> a)
-> (forall a. Num a => NonNullMap k a -> a)
-> (forall a. Num a => NonNullMap k a -> a)
-> Foldable (NonNullMap k)
forall a. Eq a => a -> NonNullMap k a -> Bool
forall a. Num a => NonNullMap k a -> a
forall a. Ord a => NonNullMap k a -> a
forall m. Monoid m => NonNullMap k m -> m
forall a. NonNullMap k a -> Bool
forall a. NonNullMap k a -> Int
forall a. NonNullMap k a -> [a]
forall a. (a -> a -> a) -> NonNullMap k a -> a
forall k a. Eq a => a -> NonNullMap k a -> Bool
forall k a. Num a => NonNullMap k a -> a
forall k a. Ord a => NonNullMap k a -> a
forall m a. Monoid m => (a -> m) -> NonNullMap k a -> m
forall k m. Monoid m => NonNullMap k m -> m
forall m a. Monoid m => (a -> m) -> NonNullMap k a -> m
forall k a. NonNullMap k a -> Bool
forall k a. NonNullMap k a -> Int
forall k a. NonNullMap k a -> [a]
forall b a. (b -> a -> b) -> b -> NonNullMap k a -> b
forall a b. (a -> b -> b) -> b -> NonNullMap k a -> b
forall k a. (a -> a -> a) -> NonNullMap k a -> a
forall k m a. Monoid m => (a -> m) -> NonNullMap k a -> m
forall k b a. (b -> a -> b) -> b -> NonNullMap k a -> b
forall k a b. (a -> b -> b) -> b -> NonNullMap k a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall k m. Monoid m => NonNullMap k m -> m
fold :: forall m. Monoid m => NonNullMap k m -> m
$cfoldMap :: forall k m a. Monoid m => (a -> m) -> NonNullMap k a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> NonNullMap k a -> m
$cfoldMap' :: forall k m a. Monoid m => (a -> m) -> NonNullMap k a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> NonNullMap k a -> m
$cfoldr :: forall k a b. (a -> b -> b) -> b -> NonNullMap k a -> b
foldr :: forall a b. (a -> b -> b) -> b -> NonNullMap k a -> b
$cfoldr' :: forall k a b. (a -> b -> b) -> b -> NonNullMap k a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> NonNullMap k a -> b
$cfoldl :: forall k b a. (b -> a -> b) -> b -> NonNullMap k a -> b
foldl :: forall b a. (b -> a -> b) -> b -> NonNullMap k a -> b
$cfoldl' :: forall k b a. (b -> a -> b) -> b -> NonNullMap k a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> NonNullMap k a -> b
$cfoldr1 :: forall k a. (a -> a -> a) -> NonNullMap k a -> a
foldr1 :: forall a. (a -> a -> a) -> NonNullMap k a -> a
$cfoldl1 :: forall k a. (a -> a -> a) -> NonNullMap k a -> a
foldl1 :: forall a. (a -> a -> a) -> NonNullMap k a -> a
$ctoList :: forall k a. NonNullMap k a -> [a]
toList :: forall a. NonNullMap k a -> [a]
$cnull :: forall k a. NonNullMap k a -> Bool
null :: forall a. NonNullMap k a -> Bool
$clength :: forall k a. NonNullMap k a -> Int
length :: forall a. NonNullMap k a -> Int
$celem :: forall k a. Eq a => a -> NonNullMap k a -> Bool
elem :: forall a. Eq a => a -> NonNullMap k a -> Bool
$cmaximum :: forall k a. Ord a => NonNullMap k a -> a
maximum :: forall a. Ord a => NonNullMap k a -> a
$cminimum :: forall k a. Ord a => NonNullMap k a -> a
minimum :: forall a. Ord a => NonNullMap k a -> a
$csum :: forall k a. Num a => NonNullMap k a -> a
sum :: forall a. Num a => NonNullMap k a -> a
$cproduct :: forall k a. Num a => NonNullMap k a -> a
product :: forall a. Num a => NonNullMap k a -> a
Foldable) via Map k
    deriving ((forall k. Eq k => Eq1 (NonNullMap k)) =>
(forall a b c d.
 (a -> b -> Bool)
 -> (c -> d -> Bool) -> NonNullMap a c -> NonNullMap b d -> Bool)
-> Eq2 NonNullMap
forall k. Eq k => Eq1 (NonNullMap k)
forall a b c d.
(a -> b -> Bool)
-> (c -> d -> Bool) -> NonNullMap a c -> NonNullMap b d -> Bool
forall (f :: * -> * -> *).
(forall a. Eq a => Eq1 (f a)) =>
(forall a b c d.
 (a -> b -> Bool) -> (c -> d -> Bool) -> f a c -> f b d -> Bool)
-> Eq2 f
$cliftEq2 :: forall a b c d.
(a -> b -> Bool)
-> (c -> d -> Bool) -> NonNullMap a c -> NonNullMap b d -> Bool
liftEq2 :: forall a b c d.
(a -> b -> Bool)
-> (c -> d -> Bool) -> NonNullMap a c -> NonNullMap b d -> Bool
Eq2, (forall k. Show k => Show1 (NonNullMap k)) =>
(forall a b.
 (Int -> a -> ShowS)
 -> ([a] -> ShowS)
 -> (Int -> b -> ShowS)
 -> ([b] -> ShowS)
 -> Int
 -> NonNullMap a b
 -> ShowS)
-> (forall a b.
    (Int -> a -> ShowS)
    -> ([a] -> ShowS)
    -> (Int -> b -> ShowS)
    -> ([b] -> ShowS)
    -> [NonNullMap a b]
    -> ShowS)
-> Show2 NonNullMap
forall k. Show k => Show1 (NonNullMap k)
forall a b.
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> Int
-> NonNullMap a b
-> ShowS
forall a b.
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> [NonNullMap a b]
-> ShowS
forall (f :: * -> * -> *).
(forall a. Show a => Show1 (f a)) =>
(forall a b.
 (Int -> a -> ShowS)
 -> ([a] -> ShowS)
 -> (Int -> b -> ShowS)
 -> ([b] -> ShowS)
 -> Int
 -> f a b
 -> ShowS)
-> (forall a b.
    (Int -> a -> ShowS)
    -> ([a] -> ShowS)
    -> (Int -> b -> ShowS)
    -> ([b] -> ShowS)
    -> [f a b]
    -> ShowS)
-> Show2 f
$cliftShowsPrec2 :: forall a b.
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> Int
-> NonNullMap a b
-> ShowS
liftShowsPrec2 :: forall a b.
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> Int
-> NonNullMap a b
-> ShowS
$cliftShowList2 :: forall a b.
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> [NonNullMap a b]
-> ShowS
liftShowList2 :: forall a b.
(Int -> a -> ShowS)
-> ([a] -> ShowS)
-> (Int -> b -> ShowS)
-> ([b] -> ShowS)
-> [NonNullMap a b]
-> ShowS
Show2, (forall m. Monoid m => NonNullMap m m -> m)
-> (forall m a b.
    Monoid m =>
    (a -> m) -> (b -> m) -> NonNullMap a b -> m)
-> (forall a c b.
    (a -> c -> c) -> (b -> c -> c) -> c -> NonNullMap a b -> c)
-> (forall c a b.
    (c -> a -> c) -> (c -> b -> c) -> c -> NonNullMap a b -> c)
-> Bifoldable NonNullMap
forall m. Monoid m => NonNullMap m m -> m
forall m a b.
Monoid m =>
(a -> m) -> (b -> m) -> NonNullMap a b -> m
forall c a b.
(c -> a -> c) -> (c -> b -> c) -> c -> NonNullMap a b -> c
forall a c b.
(a -> c -> c) -> (b -> c -> c) -> c -> NonNullMap a b -> c
forall (p :: * -> * -> *).
(forall m. Monoid m => p m m -> m)
-> (forall m a b. Monoid m => (a -> m) -> (b -> m) -> p a b -> m)
-> (forall a c b.
    (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c)
-> (forall c a b.
    (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c)
-> Bifoldable p
$cbifold :: forall m. Monoid m => NonNullMap m m -> m
bifold :: forall m. Monoid m => NonNullMap m m -> m
$cbifoldMap :: forall m a b.
Monoid m =>
(a -> m) -> (b -> m) -> NonNullMap a b -> m
bifoldMap :: forall m a b.
Monoid m =>
(a -> m) -> (b -> m) -> NonNullMap a b -> m
$cbifoldr :: forall a c b.
(a -> c -> c) -> (b -> c -> c) -> c -> NonNullMap a b -> c
bifoldr :: forall a c b.
(a -> c -> c) -> (b -> c -> c) -> c -> NonNullMap a b -> c
$cbifoldl :: forall c a b.
(c -> a -> c) -> (c -> b -> c) -> c -> NonNullMap a b -> c
bifoldl :: forall c a b.
(c -> a -> c) -> (c -> b -> c) -> c -> NonNullMap a b -> c
Bifoldable) via Map

-- Strictly speaking, this type role annotation is redundant, as:
--
-- - The type parameter 'k' already has a nominal role inherited from 'Map'.
-- - The type parameter 'v' already has a nominal role inherited from 'NonNull'.
--
-- But we reassert these roles here, so that they cannot be silently weakened
-- by a future change to the representation of 'NonNullMap'.
--
type role NonNullMap nominal nominal

-- | Converts a 'NonNullMap' into an ordinary map.
--
toMap :: NonNullMap k v -> Map k v
toMap :: forall k v. NonNullMap k v -> Map k v
toMap = NonNullMap k v -> Map k v
forall a b. Coercible a b => a -> b
coerce
{-# INLINE toMap #-}

-- | /Unsafely/ converts an ordinary map into a 'NonNullMap'.
--
-- This function /expects/ but does /not/ check that no value in the given map
-- is null. It must only be applied to maps that satisfy this condition.
--
unsafeFromMap :: Map k v -> NonNullMap k v
unsafeFromMap :: forall k v. Map k v -> NonNullMap k v
unsafeFromMap = Map k v -> NonNullMap k v
forall a b. Coercible a b => a -> b
coerce
{-# INLINE unsafeFromMap #-}