{-# LANGUAGE RankNTypes #-}
-- | Utility functions for working with beam
--
-- These are not exported from Data.Record.Beam, and should be considered
-- internal use only.
module Data.Record.Beam.Internal (
    -- * Working with Columnar'
    liftColumnarA2
  , liftNullableA2
  ) where

import Data.Coerce (coerce)
import Data.Proxy
import Database.Beam.Schema.Tables

{-------------------------------------------------------------------------------
  Working with Columnar'
-------------------------------------------------------------------------------}

liftColumnarA2 ::
     Functor m
  => Proxy x
  -> (Columnar' f x -> Columnar' g x -> m (Columnar' h x))
  -> (Columnar  f x -> Columnar  g x -> m (Columnar  h x))
liftColumnarA2 :: forall (m :: * -> *) x (f :: * -> *) (g :: * -> *) (h :: * -> *).
Functor m =>
Proxy x
-> (Columnar' f x -> Columnar' g x -> m (Columnar' h x))
-> Columnar f x
-> Columnar g x
-> m (Columnar h x)
liftColumnarA2 Proxy x
_ Columnar' f x -> Columnar' g x -> m (Columnar' h x)
f Columnar f x
fx Columnar g x
gx = Columnar' h x -> Columnar h x
forall (f :: * -> *) a. Columnar' f a -> Columnar f a
getColumnar' (Columnar' h x -> Columnar h x)
-> m (Columnar' h x) -> m (Columnar h x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Columnar' f x -> Columnar' g x -> m (Columnar' h x)
f (Columnar f x -> Columnar' f x
forall (f :: * -> *) a. Columnar f a -> Columnar' f a
Columnar' Columnar f x
fx) (Columnar g x -> Columnar' g x
forall (f :: * -> *) a. Columnar f a -> Columnar' f a
Columnar' Columnar g x
gx)

liftNullableA2 ::
     Functor m
  => (forall x. Columnar'           f  x -> Columnar'           g  x -> m (Columnar'           h  x))
  -> (forall x. Columnar' (Nullable f) x -> Columnar' (Nullable g) x -> m (Columnar' (Nullable h) x))
liftNullableA2 :: forall (m :: * -> *) (f :: * -> *) (g :: * -> *) (h :: * -> *).
Functor m =>
(forall x. Columnar' f x -> Columnar' g x -> m (Columnar' h x))
-> forall x.
   Columnar' (Nullable f) x
   -> Columnar' (Nullable g) x -> m (Columnar' (Nullable h) x)
liftNullableA2 forall x. Columnar' f x -> Columnar' g x -> m (Columnar' h x)
f Columnar' (Nullable f) x
x Columnar' (Nullable g) x
y = Columnar' h (Maybe x) -> Columnar' (Nullable h) x
forall (w :: * -> *) a.
Columnar' w (Maybe a) -> Columnar' (Nullable w) a
toNullable (Columnar' h (Maybe x) -> Columnar' (Nullable h) x)
-> m (Columnar' h (Maybe x)) -> m (Columnar' (Nullable h) x)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Columnar' f (Maybe x)
-> Columnar' g (Maybe x) -> m (Columnar' h (Maybe x))
forall x. Columnar' f x -> Columnar' g x -> m (Columnar' h x)
f (Columnar' (Nullable f) x -> Columnar' f (Maybe x)
forall (w :: * -> *) a.
Columnar' (Nullable w) a -> Columnar' w (Maybe a)
fromNullable Columnar' (Nullable f) x
x) (Columnar' (Nullable g) x -> Columnar' g (Maybe x)
forall (w :: * -> *) a.
Columnar' (Nullable w) a -> Columnar' w (Maybe a)
fromNullable Columnar' (Nullable g) x
y)
  where
    toNullable :: Columnar' w (Maybe a) -> Columnar' (Nullable w) a
    toNullable :: forall (w :: * -> *) a.
Columnar' w (Maybe a) -> Columnar' (Nullable w) a
toNullable = Columnar' w (Maybe a) -> Columnar' (Nullable w) a
forall a b. Coercible a b => a -> b
coerce

    fromNullable :: Columnar' (Nullable w) a -> Columnar' w (Maybe a)
    fromNullable :: forall (w :: * -> *) a.
Columnar' (Nullable w) a -> Columnar' w (Maybe a)
fromNullable = Columnar' (Nullable w) a -> Columnar' w (Maybe a)
forall a b. Coercible a b => a -> b
coerce

{-------------------------------------------------------------------------------
  Internal auxiliary
-------------------------------------------------------------------------------}

getColumnar' :: Columnar' f a -> Columnar f a
getColumnar' :: forall (f :: * -> *) a. Columnar' f a -> Columnar f a
getColumnar' (Columnar' Columnar f a
x) = Columnar f a
x