hset-2.1.0: src/Data/HSet/SubHSet.hs
module Data.HSet.SubHSet
( SubHSet(..)
, SubHSettable
, hnarrow
) where
import Data.HSet.Get
import Data.HSet.Type
import Data.HSet.TypeLevel
#if !(MIN_VERSION_base(4, 8, 0))
import Control.Applicative
#endif
{- $setup
>>> import Data.Proxy
-}
{- | Takes subset of some hset, including subset of same elements in
different order
>>> let x = (HSCons "hello" $ HSCons 1234 $ HSCons 12.123 HSNil) :: HSet '[String, Int, Double]
>>> subHSet x :: HSet '[Double, Int]
HSCons (12.123) (HSCons (1234) (HSNil))
>>> subHSet x :: HSet '[String, Double]
HSCons ("hello") (HSCons (12.123) (HSNil))
>>> subHSet x :: HSet '[Int, String]
HSCons (1234) (HSCons ("hello") (HSNil))
-}
class (eq ~ TEq els els2)
=> SubHSet els els2 eq where
subHSet :: HSet els -> HSet els2
instance (eq ~ TEq els '[]) => SubHSet els '[] eq where
subHSet _ = HSNil
instance ( HGettable els el, 'False ~ Elem el els2
, SubHSet els els2 subeq
, 'False ~ TEq els (el ': els2) )
=> SubHSet els (el ': els2) 'False where
subHSet h = HSCons (hget h :: el) (subHSet h :: HSet els2)
instance ( HGettable els el, 'False ~ Elem el els2
, SubHSet els els2 subeq
, els ~ (el ': els2)
, 'True ~ TEq els (el ': els2) )
=> SubHSet els (el ': els2) 'True where
subHSet h = h
type SubHSettable els1 els2 = (SubHSet els1 els2 (TEq els1 els2))
{- | Like 'subHSet' but with proxy for convenience
>>> let x = (HSCons "hello" $ HSCons 123 $ HSCons 345 HSNil) :: HSet '[String, Int, Integer]
>>> hnarrow (Proxy :: Proxy '[]) x
HSNil
>>> hnarrow (Proxy :: Proxy '[String]) x
HSCons ("hello") (HSNil)
>>> hnarrow (Proxy :: Proxy '[Int, Integer]) x
HSCons (123) (HSCons (345) (HSNil))
>>> hnarrow (Proxy :: Proxy '[Integer, Int]) x
HSCons (345) (HSCons (123) (HSNil))
-}
hnarrow :: (SubHSettable els subels)
=> proxy subels -> HSet els -> HSet subels
hnarrow _ = subHSet