{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeInType #-}
{-# OPTIONS_HADDOCK not-home #-}
module Optics.Internal.Optic.TypeLevel where
import Data.Kind (Type)
import GHC.TypeLits
type IxList = [Type]
type NoIx = ('[] :: IxList)
type WithIx i = ('[i] :: IxList)
type family QuoteType (x :: Type) :: ErrorMessage where
QuoteType x = 'Text "‘" ':<>: 'ShowType x ':<>: 'Text "’"
type family QuoteSymbol (x :: Symbol) :: ErrorMessage where
QuoteSymbol x = 'Text "‘" ':<>: 'Text x ':<>: 'Text "’"
type family ShowSymbolWithOrigin symbol origin :: ErrorMessage where
ShowSymbolWithOrigin symbol origin = 'Text " "
':<>: QuoteSymbol symbol
':<>: 'Text " (from "
':<>: 'Text origin
':<>: 'Text ")"
type family ShowSymbolsWithOrigin (fs :: [(Symbol, Symbol)]) :: ErrorMessage where
ShowSymbolsWithOrigin '[ '(symbol, origin) ] =
ShowSymbolWithOrigin symbol origin
ShowSymbolsWithOrigin ('(symbol, origin) ': rest) =
ShowSymbolWithOrigin symbol origin ':$$: ShowSymbolsWithOrigin rest
type family ShowOperators (ops :: [Symbol]) :: ErrorMessage where
ShowOperators '[op] =
QuoteSymbol op ':<>: 'Text " (from Optics.Operators)"
ShowOperators (op ': rest) =
QuoteSymbol op ':<>: 'Text " " ':<>: ShowOperators rest
type family AppendEliminations a b where
AppendEliminations '(fs1, ops1) '(fs2, ops2) =
'(Append fs1 fs2, Append ops1 ops2)
type family ShowEliminations forms :: ErrorMessage where
ShowEliminations '(fs, ops) =
ShowSymbolsWithOrigin fs ':$$: 'Text " " ':<>: ShowOperators ops
data RepDefined = RepDefined
type family AnyHasRep (s :: Type -> Type) (t :: Type -> Type) :: RepDefined
type instance AnyHasRep (s x) t = 'RepDefined
type instance AnyHasRep s (t x) = 'RepDefined
type family Curry (xs :: IxList) (y :: Type) :: Type where
Curry '[] y = y
Curry (x ': xs) y = x -> Curry xs y
type family Append (xs :: [k]) (ys :: [k]) :: [k] where
Append '[] ys = ys
Append xs '[] = xs
Append (x ': xs) ys = x ': Append xs ys
class CurryCompose xs where
composeN :: (i -> j) -> Curry xs i -> Curry xs j
instance CurryCompose '[] where
composeN = id
{-# INLINE composeN #-}
instance CurryCompose xs => CurryCompose (x ': xs) where
composeN ij f = composeN @xs ij . f
{-# INLINE composeN #-}