{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}

-- | Common decoding combinators
-- 
-- @since 0.3.0.0
module Data.TypedEncoding.Instances.Support.Decode where

import           Data.TypedEncoding.Instances.Support.Unsafe
import           Data.TypedEncoding.Common.Types.Decoding
import           Data.Proxy
import           Data.TypedEncoding.Common.Types

-- * Universal decoding for all "r-" types

-- | 
--
-- @since 0.3.0.0
decAnyR :: forall r f c str . (Restriction r, Applicative f) => Decoding f r r c str
decAnyR :: Decoding f r r c str
decAnyR = forall (alg :: Symbol) (r :: Symbol) (f :: * -> *) c str.
(Restriction r, Applicative f) =>
Decoding f r alg c str
forall (f :: * -> *) c str.
(Restriction r, Applicative f) =>
Decoding f r r c str
decAnyR' @r @r

-- |
-- @since 0.3.0.0
decAnyR' :: forall alg r f c str . (Restriction r, Applicative f) => Decoding f r alg c str
decAnyR' :: Decoding f r alg c str
decAnyR' = Proxy @Symbol r
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol r xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Decoding f r alg c str
forall (nm :: Symbol) conf str (f :: * -> *) (alg :: Symbol).
Proxy @Symbol nm
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) conf str
    -> f (Enc @[Symbol] xs conf str))
-> Decoding f nm alg conf str
UnsafeMkDecoding Proxy @Symbol r
forall k (t :: k). Proxy @k t
Proxy ((str -> str)
-> Enc @[Symbol] ((':) @Symbol r xs) c str
-> f (Enc @[Symbol] xs c str)
forall k1 k2 (f :: * -> *) str (enc1 :: k1) conf (enc2 :: k2).
Applicative f =>
(str -> str) -> Enc @k1 enc1 conf str -> f (Enc @k2 enc2 conf str)
implTranP str -> str
forall a. a -> a
id) 

-- |
-- @since 0.3.0.0
decAnyR_ :: forall r f c str alg . (Restriction r, Algorithm r alg, Applicative f) => Decoding f r alg c str
decAnyR_ :: Decoding f r alg c str
decAnyR_ = (forall (xs :: [Symbol]).
 Enc @[Symbol] ((':) @Symbol r xs) c str
 -> f (Enc @[Symbol] xs c str))
-> Decoding f r (AlgNm r) c str
forall (f :: * -> *) (nm :: Symbol) conf str.
(forall (xs :: [Symbol]).
 Enc @[Symbol] ((':) @Symbol nm xs) conf str
 -> f (Enc @[Symbol] xs conf str))
-> Decoding f nm (AlgNm nm) conf str
_mkDecoding ((forall (xs :: [Symbol]).
  Enc @[Symbol] ((':) @Symbol r xs) c str
  -> f (Enc @[Symbol] xs c str))
 -> Decoding f r (AlgNm r) c str)
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol r xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Decoding f r (AlgNm r) c str
forall a b. (a -> b) -> a -> b
$ (str -> str)
-> Enc @[Symbol] ((':) @Symbol r xs) c str
-> f (Enc @[Symbol] xs c str)
forall k1 k2 (f :: * -> *) str (enc1 :: k1) conf (enc2 :: k2).
Applicative f =>
(str -> str) -> Enc @k1 enc1 conf str -> f (Enc @k2 enc2 conf str)
implTranP str -> str
forall a. a -> a
id


-- * v0.2 style decoding combinators

-- * Compiler figure out algorithm, these appear fast enough 

_implDecodingF :: forall nm f c str . Functor f => (str -> f str) -> Decoding f nm (AlgNm nm) c str
_implDecodingF :: (str -> f str) -> Decoding f nm (AlgNm nm) c str
_implDecodingF str -> f str
f = (forall (xs :: [Symbol]).
 Enc @[Symbol] ((':) @Symbol nm xs) c str
 -> f (Enc @[Symbol] xs c str))
-> Decoding f nm (AlgNm nm) c str
forall (f :: * -> *) (nm :: Symbol) conf str.
(forall (xs :: [Symbol]).
 Enc @[Symbol] ((':) @Symbol nm xs) conf str
 -> f (Enc @[Symbol] xs conf str))
-> Decoding f nm (AlgNm nm) conf str
_mkDecoding ((forall (xs :: [Symbol]).
  Enc @[Symbol] ((':) @Symbol nm xs) c str
  -> f (Enc @[Symbol] xs c str))
 -> Decoding f nm (AlgNm nm) c str)
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Decoding f nm (AlgNm nm) c str
forall a b. (a -> b) -> a -> b
$ (str -> f str)
-> Enc @[Symbol] ((':) @Symbol nm xs) c str
-> f (Enc @[Symbol] xs c str)
forall k1 k2 (f :: * -> *) str (enc1 :: k1) conf (enc2 :: k2).
Functor f =>
(str -> f str)
-> Enc @k1 enc1 conf str -> f (Enc @k2 enc2 conf str)
implTranF str -> f str
f

_implDecodingConfF :: forall nm f c str . Functor f => (c -> str -> f str) -> Decoding f nm (AlgNm nm) c str
_implDecodingConfF :: (c -> str -> f str) -> Decoding f nm (AlgNm nm) c str
_implDecodingConfF c -> str -> f str
f = (forall (xs :: [Symbol]).
 Enc @[Symbol] ((':) @Symbol nm xs) c str
 -> f (Enc @[Symbol] xs c str))
-> Decoding f nm (AlgNm nm) c str
forall (f :: * -> *) (nm :: Symbol) conf str.
(forall (xs :: [Symbol]).
 Enc @[Symbol] ((':) @Symbol nm xs) conf str
 -> f (Enc @[Symbol] xs conf str))
-> Decoding f nm (AlgNm nm) conf str
_mkDecoding ((forall (xs :: [Symbol]).
  Enc @[Symbol] ((':) @Symbol nm xs) c str
  -> f (Enc @[Symbol] xs c str))
 -> Decoding f nm (AlgNm nm) c str)
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Decoding f nm (AlgNm nm) c str
forall a b. (a -> b) -> a -> b
$ (c -> str -> f str)
-> Enc @[Symbol] ((':) @Symbol nm xs) c str
-> f (Enc @[Symbol] xs c str)
forall k1 k2 (f :: * -> *) conf str (enc1 :: k1) (enc2 :: k2).
Functor f =>
(conf -> str -> f str)
-> Enc @k1 enc1 conf str -> f (Enc @k2 enc2 conf str)
implTranF' c -> str -> f str
f


-- * Assume @alg ~ nm@ or explicit @alg@ 

implDecodingF :: forall nm f c str . Functor f => (str -> f str) -> Decoding f nm nm c str
implDecodingF :: (str -> f str) -> Decoding f nm nm c str
implDecodingF = forall (alg :: Symbol) (nm :: Symbol) (f :: * -> *) c str.
Functor f =>
(str -> f str) -> Decoding f nm alg c str
forall (f :: * -> *) c str.
Functor f =>
(str -> f str) -> Decoding f nm nm c str
implDecodingF' @nm @nm

implDecodingF' :: forall alg nm f c str . Functor f => (str -> f str) -> Decoding f nm alg c str
implDecodingF' :: (str -> f str) -> Decoding f nm alg c str
implDecodingF' str -> f str
f = Proxy @Symbol nm
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Decoding f nm alg c str
forall (nm :: Symbol) conf str (f :: * -> *) (alg :: Symbol).
Proxy @Symbol nm
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) conf str
    -> f (Enc @[Symbol] xs conf str))
-> Decoding f nm alg conf str
UnsafeMkDecoding Proxy @Symbol nm
forall k (t :: k). Proxy @k t
Proxy ((forall (xs :: [Symbol]).
  Enc @[Symbol] ((':) @Symbol nm xs) c str
  -> f (Enc @[Symbol] xs c str))
 -> Decoding f nm alg c str)
-> (forall (xs :: [Symbol]).
    Enc @[Symbol] ((':) @Symbol nm xs) c str
    -> f (Enc @[Symbol] xs c str))
-> Decoding f nm alg c str
forall a b. (a -> b) -> a -> b
$ (str -> f str)
-> Enc @[Symbol] ((':) @Symbol nm xs) c str
-> f (Enc @[Symbol] xs c str)
forall k1 k2 (f :: * -> *) str (enc1 :: k1) conf (enc2 :: k2).
Functor f =>
(str -> f str)
-> Enc @k1 enc1 conf str -> f (Enc @k2 enc2 conf str)
implTranF str -> f str
f