packages feed

WeakSets-1.6.1.0: src/Data/Simplifiable.hs

{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}

{-| Module  : WeakSets
Description : A container may be simplified internally by the call of a function 'simplify'. This is the case for 'WeakSet's
 and 'WeakMap's where duplicate elements remain in the container until the end of the lifetime of the container. Calling 'simplify' on them will remove duplicate elements.
Copyright   : Guillaume Sabbagh 2022
License     : LGPL-3.0-or-later
Maintainer  : guillaumesabbagh@protonmail.com
Stability   : experimental
Portability : portable

A container may be simplified internally by the call of a function 'simplify'. This is the case for 'WeakSet's
 and 'WeakMap's where duplicate elements remain in the container until the end of the lifetime of the container. Calling 'simplify' on them will remove duplicate elements.
 
To derive automatically 'Simplifiable', add language extensions 'DeriveAnyClass' and 'DeriveGeneric', import  'GHC.Generics' and add 'Generic' and 'Simplifiable' to the derived typeclasses of your datatype. (For example : "data Foo a = Foo (Set a) deriving (Generic, Simplifiable)".)

-}

module Data.Simplifiable
(
    Simplifiable(..),
)
where

    import qualified        Data.WeakSet        as Set
    import qualified        Data.WeakMap        as Map
    import                  Data.WeakMap.Safe
    import qualified        Data.List           as List
    import                  Data.Int
    import                  Data.Word
    import                  GHC.Generics
    
    import                  Numeric.Natural


    -- | A container may be simplified internally by the call of a function 'simplify'. This is the case for 'WeakSet's
    -- and 'WeakMap's where duplicate elements remain in the container until the end of the lifetime of the container. Calling --'simplify' on them will remove duplicate elements.
    class Simplifiable a where
        -- | A function to simplify a container recursively.
        simplify :: a -> a
        
        default simplify :: (Generic a, GSimplifiable (Rep a)) => a -> a
        simplify a = to $ gsimplify (from a)
        
    class GSimplifiable f where
        gsimplify :: f a -> f a
        
    instance GSimplifiable U1 where
        gsimplify U1 = U1
        
    instance (GSimplifiable a, GSimplifiable b) => GSimplifiable (a :*: b) where
        gsimplify (a :*: b) = (gsimplify a) :*: (gsimplify b) 
         
    instance (GSimplifiable a, GSimplifiable b) => GSimplifiable (a :+: b) where
        gsimplify (L1 a) = L1 $ gsimplify a
        gsimplify (R1 b) = R1 $ gsimplify b
        
        
    instance (GSimplifiable a) => GSimplifiable (M1 i c a) where
        gsimplify (M1 a) = M1 $ gsimplify a

    instance (Simplifiable a) => GSimplifiable (K1 i a) where
        gsimplify (K1 x) = K1 $ simplify x
       
        
        
        
        
        
        
    instance Simplifiable Bool where
        simplify = id

    instance Simplifiable Char where
        simplify = id
        
    instance Simplifiable Double where
        simplify = id

    instance Simplifiable Float where
        simplify = id

    instance Simplifiable Int where
        simplify = id

    instance Simplifiable Int8 where
        simplify = id

    instance Simplifiable Int16 where
        simplify = id

    instance Simplifiable Int32 where
        simplify = id

    instance Simplifiable Int64 where
        simplify = id
        
    instance Simplifiable Integer where
        simplify = id

    instance Simplifiable Natural where
        simplify = id
        
    instance Simplifiable Ordering where
        simplify = id
        
    instance Simplifiable Word where
        simplify = id

    instance Simplifiable Word8 where
        simplify = id

    instance Simplifiable Word16 where
        simplify = id

    instance Simplifiable Word32 where
        simplify = id

    instance Simplifiable Word64 where
        simplify = id

    instance Simplifiable () where
        simplify = id

        
    instance (Simplifiable a, Simplifiable b) => Simplifiable (a,b) where
        simplify (a,b) = (simplify a, simplify b)
        
    instance (Simplifiable a, Simplifiable b, Simplifiable c) => Simplifiable (a,b,c) where
        simplify (a,b,c) = (simplify a, simplify b, simplify c)
        
    instance (Simplifiable a, Simplifiable b, Simplifiable c, Simplifiable d) => Simplifiable (a,b,c,d) where
        simplify (a,b,c,d) = (simplify a, simplify b, simplify c, simplify d)
        
    instance (Simplifiable a, Simplifiable b, Simplifiable c, Simplifiable d, Simplifiable e) => Simplifiable (a,b,c,d,e) where
        simplify (a,b,c,d,e) = (simplify a, simplify b, simplify c, simplify d, simplify e)
        
    instance (Simplifiable a, Eq a) => Simplifiable (Set.Set a) where
        simplify s = Set.set $ Set.setToList $ simplify <$> s
        
    instance (Simplifiable k, Simplifiable v, Eq k) => Simplifiable (Map.Map k v) where
        simplify m = Map.weakMap $ Map.mapToList $ simplify <|$|> m

    instance (Simplifiable a) => Simplifiable [a] where
        simplify xs = simplify <$> xs
        
    instance (Simplifiable a) => Simplifiable (Maybe a) where
        simplify x = simplify <$> x
        
    instance (Simplifiable a, Simplifiable b) => Simplifiable (Either a b) where
        simplify (Left a) = Left $ simplify a
        simplify (Right a) = Right $ simplify a