{-# LANGUAGE GADTs #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
module Data.TypedEncoding.Internal.Class.Encoder where
import Data.TypedEncoding.Internal.Types.Enc
import Data.TypedEncoding.Internal.Class.Encode
import Data.TypedEncoding.Internal.Util.TypeLits
import GHC.TypeLits
data Encoder f (enc :: [Symbol]) (grps :: [Symbol]) conf str where
ZeroEnc :: Encoder f '[] '[] conf str
AppendEnc :: (Enc xs conf str -> f (Enc (x ': xs) conf str)) -> Encoder f xs grps conf str -> Encoder f (x ': xs) ((TakeUntil x ":") ': grps) conf str
runEncoder :: forall grps enc f c str . (Monad f) => Encoder f enc grps c str -> Enc ('[]::[Symbol]) c str -> f (Enc enc c str)
runEncoder ZeroEnc enc0 = pure enc0
runEncoder (AppendEnc fn enc) enc0 =
let re :: f (Enc _ c str) = runEncoder enc enc0
in re >>= fn
encodeFEncoder :: forall f t tg xs gxs c str . (tg ~ TakeUntil t ":", Encodings f xs gxs c str, EncodeF f (Enc xs c str) (Enc (t ': xs) c str)) => Encoder f (t ': xs) (tg ': gxs) c str
encodeFEncoder = AppendEnc (encodeF @f @(Enc xs c str) @(Enc (t ': xs) c str)) encodings
class Encodings f (enc :: [Symbol]) (grps :: [Symbol]) c str where
encodings :: Encoder f enc grps c str
instance Encodings f '[] '[] c str where
encodings = ZeroEnc