{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module Data.Singletons.Prelude.Const (
Sing(SConst, sGetConst),
SConst, GetConst,
ConstSym0, ConstSym1,
GetConstSym0, GetConstSym1
) where
import Control.Applicative
import Data.Kind (Type)
import Data.Singletons.Internal
import Data.Singletons.Prelude.Base
hiding ( Const, ConstSym0, ConstSym1
, Foldr, FoldrSym0, sFoldr )
import Data.Singletons.Prelude.Enum
import Data.Singletons.Prelude.Eq
import Data.Singletons.Prelude.Foldable
import Data.Singletons.Prelude.Instances hiding (FoldlSym0, sFoldl)
import Data.Singletons.Prelude.Monad.Internal
import Data.Singletons.Prelude.Monoid
import Data.Singletons.Prelude.Num
import Data.Singletons.Prelude.Ord
import Data.Singletons.Prelude.Semigroup.Internal
import Data.Singletons.Prelude.Show
import Data.Singletons.Promote
import Data.Singletons.Single
data instance Sing :: forall (k :: Type) (a :: Type) (b :: k). Const a b -> Type where
SConst :: { sGetConst :: Sing a } -> Sing ('Const a)
type SConst = (Sing :: Const a b -> Type)
instance SingKind a => SingKind (Const a b) where
type Demote (Const a b) = Const (Demote a) b
fromSing (SConst sa) = Const (fromSing sa)
toSing (Const a) = withSomeSing a $ SomeSing . SConst
instance SingI a => SingI ('Const a) where
sing = SConst sing
$(genDefunSymbols [''Const])
instance SingI ConstSym0 where
sing = singFun1 SConst
instance SingI (TyCon1 'Const) where
sing = singFun1 SConst
$(singletons [d|
type family GetConst (x :: Const a b) :: a where
GetConst ('Const x) = x
|])
$(singletonsOnly [d|
deriving instance Bounded a => Bounded (Const a b)
deriving instance Eq a => Eq (Const a b)
deriving instance Ord a => Ord (Const a b)
instance Enum a => Enum (Const a b) where
succ (Const x) = Const (succ x)
pred (Const x) = Const (pred x)
toEnum i = Const (toEnum i)
fromEnum (Const x) = fromEnum x
enumFromTo (Const x) (Const y) = map Const (enumFromTo x y)
enumFromThenTo (Const x) (Const y) (Const z) =
map Const (enumFromThenTo x y z)
instance Monoid a => Monoid (Const a b) where
mempty = Const mempty
instance Num a => Num (Const a b) where
Const x + Const y = Const (x + y)
Const x - Const y = Const (x - y)
Const x * Const y = Const (x * y)
negate (Const x) = Const (negate x)
abs (Const x) = Const (abs x)
signum (Const x) = Const (signum x)
fromInteger n = Const (fromInteger n)
instance Semigroup a => Semigroup (Const a b) where
Const x <> Const y = Const (x <> y)
instance Show a => Show (Const a b) where
showsPrec d (Const x) = showParen (d > 10) $
showString "Const " . showsPrec 11 x
deriving instance Functor (Const m)
deriving instance Foldable (Const m)
instance Monoid m => Applicative (Const m) where
pure _ = Const mempty
liftA2 _ (Const x) (Const y) = Const (x `mappend` y)
Const x <*> Const y = Const (x `mappend` y)
|])