{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.HasEmpty where
import Data.Functor.Identity
import Data.Map (Map)
import Data.Sequence
import Data.Set (Set)
import Data.Text (Text)
import qualified Data.Text as Text
import Generics.SOP
import Generics.SOP.Constraint hiding (Compose)
class HasEmpty a where
emptyValue :: a
default emptyValue :: (Generic a , HasEmptyCode (Code a) , All HasEmpty (Head (Code a))) => a
emptyValue = gEmptyValue
instance HasEmpty Bool where emptyValue = False
instance HasEmpty Char where emptyValue = '?'
instance HasEmpty Int where emptyValue = 0
instance HasEmpty Double where emptyValue = 0
instance HasEmpty Text where emptyValue = Text.pack emptyValue
instance HasEmpty [a] where emptyValue = []
instance HasEmpty (Maybe a) where emptyValue = Nothing
instance HasEmpty () where emptyValue = ()
instance (HasEmpty a, HasEmpty b) => HasEmpty (a,b) where emptyValue = (emptyValue, emptyValue)
instance HasEmpty a => HasEmpty (Identity a) where emptyValue = Identity emptyValue
instance Ord k => HasEmpty (Map k v) where emptyValue = mempty
instance Ord k => HasEmpty (Set k) where emptyValue = mempty
instance HasEmpty (Seq k) where emptyValue = mempty
class HasEmptyCode (xs :: [k])
instance HasEmptyCode (x ': xs)
gEmptyValue :: forall a. ( Generic a , HasEmptyCode (Code a) , All HasEmpty (Head (Code a))) => a
gEmptyValue = case sList :: SList (Code a) of
SCons -> to $ SOP $ Z $ hcpure (Proxy @ HasEmpty) (I emptyValue)
SNil -> error "unreachable"