-- | Constructing singleton collections.

module Agda.Utils.Singleton where

import Data.Monoid (Endo(..))

import Data.Hashable (Hashable)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Data.HashSet (HashSet)
import qualified Data.HashSet as HashSet
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NonEmpty

import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.IntSet (IntSet)
import qualified Data.IntSet as IntSet

import Data.Map (Map)
import qualified Data.Map as Map
import Data.Sequence (Seq)
import qualified Data.Sequence as Seq
import Data.Set (Set)
import qualified Data.Set as Set

class Singleton el coll | coll -> el where
  singleton :: el -> coll

instance Singleton a   (Maybe a)   where singleton :: a -> Maybe a
singleton = a -> Maybe a
forall a. a -> Maybe a
Just
instance Singleton a   [a]         where singleton :: a -> [a]
singleton = (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[])
instance Singleton a  ([a] -> [a]) where singleton :: a -> [a] -> [a]
singleton = (:)
instance Singleton a   (Endo [a])  where singleton :: a -> Endo [a]
singleton = ([a] -> [a]) -> Endo [a]
forall a. (a -> a) -> Endo a
Endo (([a] -> [a]) -> Endo [a]) -> (a -> [a] -> [a]) -> a -> Endo [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:)
instance Singleton a   (NonEmpty a)
                                   where singleton :: a -> NonEmpty a
singleton = (a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [])
instance Singleton a   (Seq a)     where singleton :: a -> Seq a
singleton = a -> Seq a
forall a. a -> Seq a
Seq.singleton
instance Singleton a   (Set a)     where singleton :: a -> Set a
singleton = a -> Set a
forall a. a -> Set a
Set.singleton
instance Singleton Int IntSet      where singleton :: Int -> IntSet
singleton = Int -> IntSet
IntSet.singleton

instance Singleton (k  ,a) (Map  k a) where singleton :: (k, a) -> Map k a
singleton = (k -> a -> Map k a) -> (k, a) -> Map k a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry k -> a -> Map k a
forall k a. k -> a -> Map k a
Map.singleton
instance Singleton (Int,a) (IntMap a) where singleton :: (Int, a) -> IntMap a
singleton = (Int -> a -> IntMap a) -> (Int, a) -> IntMap a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> a -> IntMap a
forall a. Int -> a -> IntMap a
IntMap.singleton

instance Hashable a => Singleton a     (HashSet   a) where singleton :: a -> HashSet a
singleton = a -> HashSet a
forall a. Hashable a => a -> HashSet a
HashSet.singleton
instance Hashable k => Singleton (k,a) (HashMap k a) where singleton :: (k, a) -> HashMap k a
singleton = (k -> a -> HashMap k a) -> (k, a) -> HashMap k a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry k -> a -> HashMap k a
forall k v. Hashable k => k -> v -> HashMap k v
HashMap.singleton

-- Testing newtype-deriving:

-- newtype Wrap c = Wrap c
--   deriving (Singleton k)  -- Succeeds

-- Type family version:

-- class Singleton c where
--   type Elem c
--   singleton :: Elem c -> c

-- instance Singleton [a] where
--   type Elem [a] = a
--   singleton = (:[])

-- instance Singleton (Maybe a) where
--   type Elem (Maybe a) = a
--   singleton = Just

-- instance Singleton (Set a) where
--   type Elem (Set a) = a
--   singleton = Set.singleton

-- instance Singleton (Map k a) where
--   type Elem (Map k a) = (k,a)
--   singleton = uncurry Map.singleton

-- newtype Wrap a = Wrap a
--   deriving (Singleton)  -- Fails