BoomBoom
- Package
- purescript-boomboom
- Repository
- paluh/purescript-boomboom
#BoomBoom Source
newtype BoomBoom tok a
Our core type - nearly an iso:
{ ser: a → tok, prs: tok → Maybe a }
Constructors
Instances
#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
).
Constructors
Instances
#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.
#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
.
Constructors
ProductBuilder (BoomBoomD tok a (r -> r'))
Instances
(Semigroup tok) => Semigroupoid (ProductBuilder tok a)
(Monoid tok) => Category (ProductBuilder tok a)
#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.
Constructors
CoproductBuilder (BoomBoomD tok ((v -> v') -> tok) a)
Instances
(Semigroup tok) => Semigroupoid (CoproductBuilder tok a)
#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)
#buildRecord Source
buildRecord :: forall tok r. ProductBuilder tok r (Record ()) r -> BoomBoom tok r
This
Alt
instance is somewhat dangerous - it allows you to define inconsistentBoomBoom
. For example in case of coproduct type you can gettok's
mempty
value as a result of serialization which is not parsable by the sameBoomBoom
.