{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
module Data.TypedEncoding.Instances.Support.Bool where
import Data.TypedEncoding.Combinators.Unsafe
import Data.TypedEncoding.Common.Types.Enc
import Data.Proxy
import Data.TypedEncoding.Common.Types
import GHC.TypeLits
implEncOr' :: forall alg alg1 alg2 nm nm1 nm2 c str . (KnownSymbol nm) =>
Encoding (Either EncodeEx) nm1 alg1 c str
-> Encoding (Either EncodeEx) nm2 alg2 c str
-> Encoding (Either EncodeEx) nm alg c str
implEncOr' enc1 enc2 = UnsafeMkEncoding Proxy f
where
f :: forall xs . Enc xs c str -> Either EncodeEx (Enc (nm ': xs) c str)
f enc =
case runEncoding' @alg1 @nm1 enc1 enc of
Right r -> Right $ withUnsafeCoerce id r
Left (EncodeEx _ err1) ->
case runEncoding' @alg2 @nm2 enc2 enc of
Right r -> Right $ withUnsafeCoerce id r
Left (EncodeEx _ err2) -> Left $ EncodeEx (Proxy :: Proxy nm) (err1, err2)
implEncOr :: forall nm nm1 nm2 c str . (KnownSymbol nm) =>
Encoding (Either EncodeEx) nm1 nm1 c str
-> Encoding (Either EncodeEx) nm2 nm2 c str
-> Encoding (Either EncodeEx) nm nm c str
implEncOr = implEncOr' @nm @nm1 @nm2
_implEncOr :: forall nm nm1 nm2 c str alg alg1 alg2.
(
KnownSymbol nm
, Algorithm nm alg
, Algorithm nm1 alg1
, Algorithm nm2 alg2
) =>
Encoding (Either EncodeEx) nm1 alg1 c str
-> Encoding (Either EncodeEx) nm2 alg2 c str
-> Encoding (Either EncodeEx) nm alg c str
_implEncOr = implEncOr' @alg @alg1 @alg2
implEncAnd' :: forall alg alg1 alg2 nm nm1 nm2 c str . (KnownSymbol nm, Eq str) =>
Encoding (Either EncodeEx) nm1 alg1 c str
-> Encoding (Either EncodeEx) nm2 alg2 c str
-> Encoding (Either EncodeEx) nm alg c str
implEncAnd' enc1 enc2 = UnsafeMkEncoding Proxy f
where
f :: forall xs . Enc xs c str -> Either EncodeEx (Enc (nm ': xs) c str)
f enc =
case (runEncoding' @alg1 @nm1 enc1 enc, runEncoding' @alg2 @nm2 enc2 enc) of
(Right r1, Right r2) -> if getPayload r1 == getPayload r2
then Right $ withUnsafeCoerce id r1
else Left $ EncodeEx (Proxy :: Proxy nm) "Non-matching encodings"
(Left (EncodeEx _ err1), Left (EncodeEx _ err2)) -> Left $ EncodeEx (Proxy :: Proxy nm) (err1, err2)
(Left (EncodeEx _ err), _) -> Left $ EncodeEx (Proxy :: Proxy nm) (err, ())
(_, Left (EncodeEx _ err)) -> Left $ EncodeEx (Proxy :: Proxy nm) ((), err)
implEncAnd :: forall nm nm1 nm2 c str . (KnownSymbol nm, Eq str) =>
Encoding (Either EncodeEx) nm1 nm1 c str
-> Encoding (Either EncodeEx) nm2 nm2 c str
-> Encoding (Either EncodeEx) nm nm c str
implEncAnd = implEncAnd' @nm @nm1 @nm2
_implEncAnd :: forall nm nm1 nm2 c str alg alg1 alg2.
(
KnownSymbol nm
, Eq str
, Algorithm nm alg
, Algorithm nm1 alg1
, Algorithm nm2 alg2
) =>
Encoding (Either EncodeEx) nm1 alg1 c str
-> Encoding (Either EncodeEx) nm2 alg2 c str
-> Encoding (Either EncodeEx) nm alg c str
_implEncAnd = implEncAnd' @alg @alg1 @alg2
implEncNot' :: forall alg alg1 nm nm1 c str . (KnownSymbol nm) =>
(str -> str)
-> Encoding (Either EncodeEx) nm1 alg1 c str
-> Encoding (Either EncodeEx) nm alg c str
implEncNot' fn enc1 = UnsafeMkEncoding Proxy f
where
f :: forall xs . Enc xs c str -> Either EncodeEx (Enc (nm ': xs) c str)
f enc =
case runEncoding' @alg1 @nm1 enc1 enc of
Left _ -> Right $ withUnsafeCoerce fn enc
Right _ -> Left $ EncodeEx (Proxy :: Proxy nm) "Negated encoding succeeded"
implEncNot :: forall nm nm1 c str . (KnownSymbol nm) =>
(str -> str)
-> Encoding (Either EncodeEx) nm1 nm1 c str
-> Encoding (Either EncodeEx) nm nm c str
implEncNot = implEncNot' @nm @nm1
_implEncNot :: forall nm nm1 c str alg alg1 .
(
KnownSymbol nm
, Algorithm nm alg
, Algorithm nm1 alg1
) =>
(str -> str)
-> Encoding (Either EncodeEx) nm1 alg1 c str
-> Encoding (Either EncodeEx) nm alg c str
_implEncNot = implEncNot' @alg @alg1
_implREncNot :: forall nm nm1 c str alg alg1 .
(
KnownSymbol nm
, Algorithm nm alg
, Algorithm nm1 alg1
) =>
Encoding (Either EncodeEx) nm1 alg1 c str
-> Encoding (Either EncodeEx) nm alg c str
_implREncNot = implEncNot' @alg @alg1 id