-- |
-- Copyright: © 2022–2025 Jonathan Knowles
-- License: Apache-2.0
--
-- A minimal non-empty variant of the 'Set' data type.
--
module Data.MonoidMap.Examples.Set.NonEmpty
    ( NESet
    , nonEmptySet
    , toSet
    , isSubsetOf
    , union
    , intersection
    ) where

import Prelude

import Data.Coerce
    ( coerce )
import Data.Set
    ( Set )

import qualified Data.Set as Set

newtype NESet v = NESet (Set v)
    deriving stock NESet v -> NESet v -> Bool
(NESet v -> NESet v -> Bool)
-> (NESet v -> NESet v -> Bool) -> Eq (NESet v)
forall v. Eq v => NESet v -> NESet v -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall v. Eq v => NESet v -> NESet v -> Bool
== :: NESet v -> NESet v -> Bool
$c/= :: forall v. Eq v => NESet v -> NESet v -> Bool
/= :: NESet v -> NESet v -> Bool
Eq
    deriving newtype (NonEmpty (NESet v) -> NESet v
NESet v -> NESet v -> NESet v
(NESet v -> NESet v -> NESet v)
-> (NonEmpty (NESet v) -> NESet v)
-> (forall b. Integral b => b -> NESet v -> NESet v)
-> Semigroup (NESet v)
forall b. Integral b => b -> NESet v -> NESet v
forall v. Ord v => NonEmpty (NESet v) -> NESet v
forall v. Ord v => NESet v -> NESet v -> NESet v
forall v b. (Ord v, Integral b) => b -> NESet v -> NESet v
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: forall v. Ord v => NESet v -> NESet v -> NESet v
<> :: NESet v -> NESet v -> NESet v
$csconcat :: forall v. Ord v => NonEmpty (NESet v) -> NESet v
sconcat :: NonEmpty (NESet v) -> NESet v
$cstimes :: forall v b. (Ord v, Integral b) => b -> NESet v -> NESet v
stimes :: forall b. Integral b => b -> NESet v -> NESet v
Semigroup, Int -> NESet v -> ShowS
[NESet v] -> ShowS
NESet v -> String
(Int -> NESet v -> ShowS)
-> (NESet v -> String) -> ([NESet v] -> ShowS) -> Show (NESet v)
forall v. Show v => Int -> NESet v -> ShowS
forall v. Show v => [NESet v] -> ShowS
forall v. Show v => NESet v -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall v. Show v => Int -> NESet v -> ShowS
showsPrec :: Int -> NESet v -> ShowS
$cshow :: forall v. Show v => NESet v -> String
show :: NESet v -> String
$cshowList :: forall v. Show v => [NESet v] -> ShowS
showList :: [NESet v] -> ShowS
Show)

nonEmptySet :: Set v -> Maybe (NESet v)
nonEmptySet :: forall v. Set v -> Maybe (NESet v)
nonEmptySet Set v
s
    | Set v -> Bool
forall a. Set a -> Bool
Set.null Set v
s = Maybe (NESet v)
forall a. Maybe a
Nothing
    | Bool
otherwise = NESet v -> Maybe (NESet v)
forall a. a -> Maybe a
Just (Set v -> NESet v
forall v. Set v -> NESet v
NESet Set v
s)

toSet :: NESet v -> Set v
toSet :: forall v. NESet v -> Set v
toSet = NESet v -> Set v
forall a b. Coercible a b => a -> b
coerce

isSubsetOf :: Ord v => NESet v -> NESet v -> Bool
isSubsetOf :: forall v. Ord v => NESet v -> NESet v -> Bool
isSubsetOf = (Set v -> Set v -> Bool) -> NESet v -> NESet v -> Bool
forall a b. Coercible a b => a -> b
coerce Set v -> Set v -> Bool
forall a. Ord a => Set a -> Set a -> Bool
Set.isSubsetOf

union :: Ord v => NESet v -> NESet v -> NESet v
union :: forall v. Ord v => NESet v -> NESet v -> NESet v
union = (Set v -> Set v -> Set v) -> NESet v -> NESet v -> NESet v
forall a b. Coercible a b => a -> b
coerce Set v -> Set v -> Set v
forall a. Ord a => Set a -> Set a -> Set a
Set.union

intersection :: Ord v => NESet v -> NESet v -> Set v
intersection :: forall v. Ord v => NESet v -> NESet v -> Set v
intersection = (Set v -> Set v -> Set v) -> NESet v -> NESet v -> Set v
forall a b. Coercible a b => a -> b
coerce Set v -> Set v -> Set v
forall a. Ord a => Set a -> Set a -> Set a
Set.intersection