{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} {- Copyright: (c) 2016 Stephen Diehl (c) 20016-2018 Serokell (c) 2018 Kowainik License: MIT -} {- | Typeclass for creating structures from singleton element. -} module Relude.Container.One ( One (..) ) where import Relude.Base (Char, Int, Word8) import Relude.Container.Reexport (HashMap, HashSet, Hashable, IntMap, IntSet, Map, Set, uncurry) import qualified Data.List.NonEmpty as NE import qualified Data.Sequence as SEQ import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BSL import qualified Data.Text as T import qualified Data.Text.Lazy as TL import qualified Data.HashMap.Strict as HM import qualified Data.HashSet as HashSet import qualified Data.IntMap as IM import qualified Data.IntSet as IS import qualified Data.Map as M import qualified Data.Set as Set -- $setup -- >>> import Relude.Base (Int, String) -- >>> import Relude.Bool (Bool (..)) -- >>> import Relude.String (Text) -- >>> import qualified Data.HashMap.Strict as HashMap {- | Type class for types that can be created from one element. @singleton@ is lone name for this function. Constructions of different type differ: @:[]@ for lists, two arguments for Maps. Also some data types are monomorphic. >>> one True :: [Bool] [True] >>> one 'a' :: Text "a" >>> one (3, "hello") :: HashMap Int String fromList [(3,"hello")] -} class One x where type OneItem x -- | Create a list, map, 'Text', etc from a single element. one :: OneItem x -> x -- Lists instance One [a] where type OneItem [a] = a one = (:[]) {-# INLINE one #-} instance One (NE.NonEmpty a) where type OneItem (NE.NonEmpty a) = a one = (NE.:|[]) {-# INLINE one #-} instance One (SEQ.Seq a) where type OneItem (SEQ.Seq a) = a one = (SEQ.empty SEQ.|>) {-# INLINE one #-} -- Monomorphic sequences instance One T.Text where type OneItem T.Text = Char one = T.singleton {-# INLINE one #-} instance One TL.Text where type OneItem TL.Text = Char one = TL.singleton {-# INLINE one #-} instance One BS.ByteString where type OneItem BS.ByteString = Word8 one = BS.singleton {-# INLINE one #-} instance One BSL.ByteString where type OneItem BSL.ByteString = Word8 one = BSL.singleton {-# INLINE one #-} -- Maps instance One (Map k v) where type OneItem (Map k v) = (k, v) one = uncurry M.singleton {-# INLINE one #-} instance Hashable k => One (HashMap k v) where type OneItem (HashMap k v) = (k, v) one = uncurry HM.singleton {-# INLINE one #-} instance One (IntMap v) where type OneItem (IntMap v) = (Int, v) one = uncurry IM.singleton {-# INLINE one #-} -- Sets instance One (Set v) where type OneItem (Set v) = v one = Set.singleton {-# INLINE one #-} instance Hashable v => One (HashSet v) where type OneItem (HashSet v) = v one = HashSet.singleton {-# INLINE one #-} instance One IntSet where type OneItem IntSet = Int one = IS.singleton {-# INLINE one #-}