#BoomBoom Source

newtype BoomBoom tok a

Our core type - nearly an iso: { ser: a → tok, prs: tok → Maybe a }



#BoomBoomD Source

newtype BoomBoomD tok a' a

D from diverging as a' can diverge from a. It is enough to express Applicative for parsing and two Semigroupoids in both directions (ser and prs).


  • BoomBoomD { prs :: tok -> Maybe { a :: a, tok :: tok }, ser :: a' -> tok }


#divergeA Source

divergeA :: forall tok a' a. (a' -> a) -> BoomBoom tok a -> BoomBoomD tok a' a

divergeA together with BoomBoomD Applicative instance form quite nice API to create by hand BoomBooms for records (or other product types):

recordB ∷ BoomBoom String {x :: Int, y :: Int}
recordB = BoomBoom $
  {x: _, y: _}
  <$> _.x >- int
  <* lit "/"
  <*> _.y >- int

This can be tedious and leaves responsibility on the user to accordingly pick and create elements of a product. For example I could easily replace _.x with _.y (and get two _.y) by mistake and it won't be detected by compiler.

#(>-) Source

Operator alias for BoomBoom.divergeA (left-associative / precedence 5)

#ProductBuilder Source

newtype ProductBuilder tok a r r'

These two semigroupoids keep track of BoomBoom divergence and allow us to define nice combinators for variant and record build up.

You should not really worry about these two types because they are underlying machinery for higher level combinators addChoice/buildVariant and addField/buildRecord.



#CoproductBuilder Source

newtype CoproductBuilder tok a v v'

For sure serializer could be expressed much easier (like: a → (b → t) → t) but we want to use BooBoomD for this and we've got ser: a'-> tok with moving a' part to our disposition.



#addChoice Source

addChoice :: forall tok n s' s r' r a. RowCons n a r' r => RowCons n a s s' => IsSymbol n => Semigroup tok => Eq tok => SProxy n -> BoomBoom tok Unit -> BoomBoom tok a -> CoproductBuilder tok (Variant s') (Either (Variant r) tok) (Either (Variant r') tok)

Our category allows us to step by step contract our variant:

    (((Either a tok → Either b tok) → tok) → tok)
>>> (((Either b tok → Either c tok) → tok) → tok)
=   (((Either a tok → Either c tok) → tok) → tok)

Where a, b, c is our contracting variant series.

#buildVariant Source

buildVariant :: forall r tok. CoproductBuilder tok (Variant r) (Either (Variant r) tok) (Either (Variant ()) tok) -> BoomBoom tok (Variant r)

We are getting our final serializer here - a function which returns

Either Void tok so we can just pick right thing from it:

ser ∷ (((Either (Variant r) tok → Either (Variant ()) tok) → tok) → tok)

#addField Source

addField :: forall tok s' s p' p n a. RowCons n a s s' => RowLacks n s => RowCons n a p p' => RowLacks n p => IsSymbol n => SProxy n -> BoomBoom tok a -> ProductBuilder tok (Record s') (Record p) (Record p')

#buildRecord Source

buildRecord :: forall tok r. ProductBuilder tok r (Record ()) r -> BoomBoom tok r

#serialize Source

serialize :: forall tok a. BoomBoom tok a -> (a -> tok)

#parse Source

parse :: forall tok a. BoomBoom tok a -> (tok -> Maybe a)

#xrap Source

xrap :: forall tok n a. Newtype n a => BoomBoom tok a -> BoomBoom tok n

Newtype wrap/unwrap