{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Waargonaut.Encode.Types
(
EncoderFns (..)
, Encoder
, Encoder'
, ObjEncoder
, ObjEncoder'
, runEncoder
, runPureEncoder
, jsonEncoder
, objEncoder
, generaliseEncoder
) where
import Control.Monad (Monad)
import Control.Monad.Morph (MFunctor (..),
generalize)
import Control.Applicative (Applicative, liftA2,
pure)
import Control.Category (id, (.))
import Control.Lens (( # ))
import Data.Either (either)
import Data.Function (const, ($))
import Data.Functor (Functor)
import Data.Functor.Contravariant (Contravariant (..))
import Data.Functor.Contravariant.Divisible (Decidable (..),
Divisible (..))
import Data.Monoid (mempty)
import Data.Semigroup ((<>))
import Data.Void (absurd)
import Data.Functor (fmap)
import Data.Functor.Identity (Identity (..))
import Waargonaut.Types (JObject, Json, WS, _JObj)
data EncoderFns i f a = EncoderFns
{ EncoderFns i f a -> i -> Json
finaliseEncoding :: i -> Json
, EncoderFns i f a -> a -> f i
initialEncoding :: a -> f i
}
instance MFunctor (EncoderFns i) where
hoist :: (forall a. m a -> n a) -> EncoderFns i m b -> EncoderFns i n b
hoist forall a. m a -> n a
nat (EncoderFns i -> Json
f b -> m i
i) = (i -> Json) -> (b -> n i) -> EncoderFns i n b
forall i (f :: * -> *) a.
(i -> Json) -> (a -> f i) -> EncoderFns i f a
EncoderFns i -> Json
f (m i -> n i
forall a. m a -> n a
nat (m i -> n i) -> (b -> m i) -> b -> n i
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. b -> m i
i)
generaliseEncoder :: Monad f => EncoderFns i Identity a -> EncoderFns i f a
generaliseEncoder :: EncoderFns i Identity a -> EncoderFns i f a
generaliseEncoder (EncoderFns i -> Json
f a -> Identity i
i) = (i -> Json) -> (a -> f i) -> EncoderFns i f a
forall i (f :: * -> *) a.
(i -> Json) -> (a -> f i) -> EncoderFns i f a
EncoderFns i -> Json
f (Identity i -> f i
forall (m :: * -> *) a. Monad m => Identity a -> m a
generalize (Identity i -> f i) -> (a -> Identity i) -> a -> f i
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> Identity i
i)
instance Contravariant (EncoderFns o f) where
contramap :: (a -> b) -> EncoderFns o f b -> EncoderFns o f a
contramap a -> b
f EncoderFns o f b
e = (o -> Json) -> (a -> f o) -> EncoderFns o f a
forall i (f :: * -> *) a.
(i -> Json) -> (a -> f i) -> EncoderFns i f a
EncoderFns (EncoderFns o f b -> o -> Json
forall i (f :: * -> *) a. EncoderFns i f a -> i -> Json
finaliseEncoding EncoderFns o f b
e) (EncoderFns o f b -> b -> f o
forall i (f :: * -> *) a. EncoderFns i f a -> a -> f i
initialEncoding EncoderFns o f b
e (b -> f o) -> (a -> b) -> a -> f o
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> b
f)
{-# INLINE contramap #-}
instance Applicative f => Divisible (EncoderFns (JObject WS Json) f) where
conquer :: EncoderFns (JObject WS Json) f a
conquer = (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall a (f :: * -> *).
(a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
objEncoder (f (JObject WS Json) -> a -> f (JObject WS Json)
forall a b. a -> b -> a
const (JObject WS Json -> f (JObject WS Json)
forall (f :: * -> *) a. Applicative f => a -> f a
pure JObject WS Json
forall a. Monoid a => a
mempty))
{-# INLINE conquer #-}
divide :: (a -> (b, c))
-> EncoderFns (JObject WS Json) f b
-> EncoderFns (JObject WS Json) f c
-> EncoderFns (JObject WS Json) f a
divide a -> (b, c)
atobc (EncoderFns JObject WS Json -> Json
_ b -> f (JObject WS Json)
oB) (EncoderFns JObject WS Json -> Json
_ c -> f (JObject WS Json)
oC) = (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall a (f :: * -> *).
(a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
objEncoder ((a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a)
-> (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall a b. (a -> b) -> a -> b
$ \a
a ->
let
(b
b,c
c) = a -> (b, c)
atobc a
a
in
(JObject WS Json -> JObject WS Json -> JObject WS Json)
-> f (JObject WS Json)
-> f (JObject WS Json)
-> f (JObject WS Json)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 JObject WS Json -> JObject WS Json -> JObject WS Json
forall a. Semigroup a => a -> a -> a
(<>) (b -> f (JObject WS Json)
oB b
b) (c -> f (JObject WS Json)
oC c
c)
{-# INLINE divide #-}
instance Applicative f => Decidable (EncoderFns (JObject WS Json) f) where
lose :: (a -> Void) -> EncoderFns (JObject WS Json) f a
lose a -> Void
f = (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall a (f :: * -> *).
(a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
objEncoder ((a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a)
-> (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall a b. (a -> b) -> a -> b
$ \a
a -> Void -> f (JObject WS Json)
forall a. Void -> a
absurd (a -> Void
f a
a)
{-# INLINE lose #-}
choose :: (a -> Either b c)
-> EncoderFns (JObject WS Json) f b
-> EncoderFns (JObject WS Json) f c
-> EncoderFns (JObject WS Json) f a
choose a -> Either b c
split (EncoderFns JObject WS Json -> Json
_ b -> f (JObject WS Json)
oB) (EncoderFns JObject WS Json -> Json
_ c -> f (JObject WS Json)
oC) = (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall a (f :: * -> *).
(a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
objEncoder ((a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a)
-> (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall a b. (a -> b) -> a -> b
$ \a
a ->
(b -> f (JObject WS Json))
-> (c -> f (JObject WS Json)) -> Either b c -> f (JObject WS Json)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either b -> f (JObject WS Json)
oB c -> f (JObject WS Json)
oC (a -> Either b c
split a
a)
{-# INLINE choose #-}
type Encoder f a = EncoderFns Json f a
type ObjEncoder f a = EncoderFns (JObject WS Json) f a
type Encoder' a = EncoderFns Json Identity a
type ObjEncoder' a = EncoderFns (JObject WS Json) Identity a
runEncoder :: Functor f => EncoderFns i f a -> a -> f Json
runEncoder :: EncoderFns i f a -> a -> f Json
runEncoder EncoderFns i f a
e = (i -> Json) -> f i -> f Json
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (EncoderFns i f a -> i -> Json
forall i (f :: * -> *) a. EncoderFns i f a -> i -> Json
finaliseEncoding EncoderFns i f a
e) (f i -> f Json) -> (a -> f i) -> a -> f Json
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. EncoderFns i f a -> a -> f i
forall i (f :: * -> *) a. EncoderFns i f a -> a -> f i
initialEncoding EncoderFns i f a
e
{-# INLINE runEncoder #-}
runPureEncoder :: EncoderFns i Identity a -> a -> Json
runPureEncoder :: EncoderFns i Identity a -> a -> Json
runPureEncoder EncoderFns i Identity a
e = Identity Json -> Json
forall a. Identity a -> a
runIdentity (Identity Json -> Json) -> (a -> Identity Json) -> a -> Json
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (i -> Json) -> Identity i -> Identity Json
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (EncoderFns i Identity a -> i -> Json
forall i (f :: * -> *) a. EncoderFns i f a -> i -> Json
finaliseEncoding EncoderFns i Identity a
e) (Identity i -> Identity Json)
-> (a -> Identity i) -> a -> Identity Json
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. EncoderFns i Identity a -> a -> Identity i
forall i (f :: * -> *) a. EncoderFns i f a -> a -> f i
initialEncoding EncoderFns i Identity a
e
{-# INLINE runPureEncoder #-}
jsonEncoder :: (a -> f Json) -> EncoderFns Json f a
jsonEncoder :: (a -> f Json) -> EncoderFns Json f a
jsonEncoder = (Json -> Json) -> (a -> f Json) -> EncoderFns Json f a
forall i (f :: * -> *) a.
(i -> Json) -> (a -> f i) -> EncoderFns i f a
EncoderFns Json -> Json
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id
{-# INLINE jsonEncoder #-}
objEncoder :: (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
objEncoder :: (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
objEncoder = (JObject WS Json -> Json)
-> (a -> f (JObject WS Json)) -> EncoderFns (JObject WS Json) f a
forall i (f :: * -> *) a.
(i -> Json) -> (a -> f i) -> EncoderFns i f a
EncoderFns (\JObject WS Json
o -> Tagged (JObject WS Json, WS) (Identity (JObject WS Json, WS))
-> Tagged Json (Identity Json)
forall r ws a. AsJType r ws a => Prism' r (JObject ws a, ws)
_JObj (Tagged (JObject WS Json, WS) (Identity (JObject WS Json, WS))
-> Tagged Json (Identity Json))
-> (JObject WS Json, WS) -> Json
forall t b. AReview t b -> b -> t
# (JObject WS Json
o, WS
forall a. Monoid a => a
mempty))
{-# INLINE objEncoder #-}