module RetroClash.Barbies
    ( Pure
    , Partial
    , Signals
    , bbundle
    , bunbundle
    ) where

import Clash.Prelude
import Data.Monoid (Last(..))
import Data.Functor.Identity

import Barbies
import Barbies.Bare

type Pure b = b Bare Identity
type Partial b = Barbie (b Covered) Last
type Signals dom b = b Covered (Signal dom)

bbundle :: (Applicative f, BareB b, TraversableB (b Covered)) => b Covered f -> f (Pure b)
bbundle :: forall (f :: Type -> Type) (b :: Type -> (Type -> Type) -> Type).
(Applicative f, BareB b, TraversableB (b Covered)) =>
b Covered f -> f (Pure b)
bbundle = (b Covered Identity -> Pure b)
-> f (b Covered Identity) -> f (Pure b)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap b Covered Identity -> Pure b
forall (b :: Type -> (Type -> Type) -> Type).
BareB b =>
b Covered Identity -> b Bare Identity
bstrip (f (b Covered Identity) -> f (Pure b))
-> (b Covered f -> f (b Covered Identity))
-> b Covered f
-> f (Pure b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. b Covered f -> f (b Covered Identity)
forall (e :: Type -> Type) (b :: (Type -> Type) -> Type).
(Applicative e, TraversableB b) =>
b e -> e (b Identity)
bsequence'

bunbundle :: (Functor f, BareB b, DistributiveB (b Covered)) => f (Pure b) -> b Covered f
bunbundle :: forall (f :: Type -> Type) (b :: Type -> (Type -> Type) -> Type).
(Functor f, BareB b, DistributiveB (b Covered)) =>
f (Pure b) -> b Covered f
bunbundle = f (b Covered Identity) -> b Covered f
forall (b :: (Type -> Type) -> Type) (f :: Type -> Type).
(DistributiveB b, Functor f) =>
f (b Identity) -> b f
bdistribute' (f (b Covered Identity) -> b Covered f)
-> (f (Pure b) -> f (b Covered Identity))
-> f (Pure b)
-> b Covered f
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Pure b -> b Covered Identity)
-> f (Pure b) -> f (b Covered Identity)
forall a b. (a -> b) -> f a -> f b
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap Pure b -> b Covered Identity
forall (b :: Type -> (Type -> Type) -> Type).
BareB b =>
b Bare Identity -> b Covered Identity
bcover

instance (BareB b, TraversableB (b Covered), DistributiveB (b Covered)) => Bundle (Pure b) where
    type Unbundled dom (Pure b) = Signals dom b
    bundle :: forall (dom :: Domain).
Unbundled dom (Pure b) -> Signal dom (Pure b)
bundle = b Covered (Signal dom) -> Signal dom (Pure b)
Unbundled dom (Pure b) -> Signal dom (Pure b)
forall (f :: Type -> Type) (b :: Type -> (Type -> Type) -> Type).
(Applicative f, BareB b, TraversableB (b Covered)) =>
b Covered f -> f (Pure b)
bbundle
    unbundle :: forall (dom :: Domain).
Signal dom (Pure b) -> Unbundled dom (Pure b)
unbundle = Signal dom (Pure b) -> b Covered (Signal dom)
Signal dom (Pure b) -> Unbundled dom (Pure b)
forall (f :: Type -> Type) (b :: Type -> (Type -> Type) -> Type).
(Functor f, BareB b, DistributiveB (b Covered)) =>
f (Pure b) -> b Covered f
bunbundle