{-# language ConstraintKinds #-}
{-# language DataKinds #-}
{-# language FlexibleContexts #-}
{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language MultiParamTypeClasses #-}
{-# language RankNTypes #-}
{-# language StandaloneKindSignatures #-}
{-# language TypeFamilies #-}
{-# language UndecidableInstances #-}
{-# language UndecidableSuperClasses #-}
module Rel8.Schema.Null
( Nullify, Unnullify
, NotNull
, Homonullable
, Nullity( Null, NotNull )
, Nullable, nullable
, Sql
)
where
import Data.Kind ( Constraint, Type )
import Prelude
type IsMaybe :: Type -> Bool
type family IsMaybe a where
IsMaybe (Maybe _) = 'True
IsMaybe _ = 'False
type Unnullify' :: Bool -> Type -> Type
type family Unnullify' isMaybe ma where
Unnullify' 'False a = a
Unnullify' 'True (Maybe a) = a
type Unnullify :: Type -> Type
type Unnullify a = Unnullify' (IsMaybe a) a
type Nullify' :: Bool -> Type -> Type
type family Nullify' isMaybe a where
Nullify' 'False a = a
Nullify' 'True a = Maybe a
type Nullify :: Type -> Type
type Nullify a = Maybe (Unnullify a)
type NotNull :: Type -> Constraint
class (Nullable a, IsMaybe a ~ 'False) => NotNull a
instance (Nullable a, IsMaybe a ~ 'False) => NotNull a
type Homonullable :: Type -> Type -> Constraint
class IsMaybe a ~ IsMaybe b => Homonullable a b
instance IsMaybe a ~ IsMaybe b => Homonullable a b
type Nullity :: Type -> Type
data Nullity a where
NotNull :: NotNull a => Nullity a
Null :: NotNull a => Nullity (Maybe a)
type Nullable' :: Bool -> Type -> Constraint
class
( IsMaybe a ~ isMaybe
, IsMaybe (Unnullify a) ~ 'False
, Nullify' isMaybe (Unnullify a) ~ a
) => Nullable' isMaybe a
where
nullable' :: Nullity a
instance IsMaybe a ~ 'False => Nullable' 'False a where
nullable' :: Nullity a
nullable' = Nullity a
forall a. NotNull a => Nullity a
NotNull
instance IsMaybe a ~ 'False => Nullable' 'True (Maybe a) where
nullable' :: Nullity (Maybe a)
nullable' = Nullity (Maybe a)
forall a. NotNull a => Nullity (Maybe a)
Null
type Nullable :: Type -> Constraint
class Nullable' (IsMaybe a) a => Nullable a
instance Nullable' (IsMaybe a) a => Nullable a
nullable :: Nullable a => Nullity a
nullable :: Nullity a
nullable = Nullity a
forall (isMaybe :: Bool) a. Nullable' isMaybe a => Nullity a
nullable'
type Sql :: (Type -> Constraint) -> Type -> Constraint
class (constraint (Unnullify a), Nullable a) => Sql constraint a
instance (constraint (Unnullify a), Nullable a) => Sql constraint a