~/bend-docscommunity

lib.bend checks

raw source on the hub · import 0xdf88d6b259873c74c8d91fe09934de63/lib.bend as Lib

Parse — tiny String parser combinators for Bend. Publish entry for this package. Depends only on Base.

Encoding: a Parser for A is String → Maybe (A & remainder). One-shot combinators (bind/or/optional/map) take ordinary Parser functions (affine closures are fine — each is used at most once). Predicates for satisfy/take_while are templates (~) so they may fire on many chars. Tradeoff: a Parser closure is not reusable; rebuild with top-level defs or lambdas at each site. String is Data, so or/optional take +s to retry.

1 import
import Base

Laws

law Parser provedsource · line 13 · raw

@-A:Type -> Type

Parser(A) ≅ String → Maybe<&1, A & String> (&1 keeps A : Type).

Definitions

def Parse.pure source · line 21 · raw

@-A:Type -> @x:A -> @s:String -> Maybe<&1, Pair(A, String)>

Always succeed with x, consuming nothing.

def Parse.fail source · line 25 · raw

@-A:Type -> @s:String -> Maybe<&1, Pair(A, String)>

Always fail.

def Parse.map source · line 29 · raw

@-A:Type -> @-B:Type -> @f:(@_:A -> B) -> @m:Maybe<&1, Pair(A, String)> -> Maybe<&1, Pair(B, String)>

Map over a successful parse payload (value only; remainder unchanged).

def Parse.bind.cont source · line 39 · raw

@-A:Type -> @-B:Type -> @f:(@_:A -> @_:String -> Maybe<&1, Pair(B, String)>) -> @m:Maybe<&1, Pair(A, String)> -> Maybe<&1, Pair(B, String)>

Run p, then continue with f(value, remainder). Helpers avoid matching on p(s).

def Parse.bind source · line 49 · raw

@-A:Type -> @-B:Type -> @p:Parser(A) -> @f:(@_:A -> @_:String -> Maybe<&1, Pair(B, String)>) -> @s:String -> Maybe<&1, Pair(B, String)>

def Parse.and_then source · line 56 · raw

@-A:Type -> @-B:Type -> @p:Parser(A) -> @f:(@_:A -> @_:String -> Maybe<&1, Pair(B, String)>) -> @s:String -> Maybe<&1, Pair(B, String)>

Alias: and_then = bind.

def Parse.or.cont source · line 63 · raw

@-A:Type -> @q:Parser(A) -> @+s:String -> @m:Maybe<&1, Pair(A, String)> -> Maybe<&1, Pair(A, String)>

Prefer p; on failure try q on the same input (+s copies; String is Data).

def Parse.or source · line 72 · raw

@-A:Type -> @p:Parser(A) -> @q:Parser(A) -> @+s:String -> Maybe<&1, Pair(A, String)>

def Parse.satisfy.go source · line 78 · raw

@+h:Char -> @t:String -> @ok:Bool -> Maybe<&1, Pair(Char, String)>

Next char if pred holds. ~pred is a template (reusable, closed).

def Parse.char.go source · line 95 · raw

@+expected:Char -> @+h:Char -> @t:String -> @ok:Bool -> Maybe<&1, Pair(Char, String)>

Exact character.

def Parse.char source · line 104 · raw

@+expected:Char -> @s:String -> Maybe<&1, Pair(Char, String)>

def Parse.string.go source · line 112 · raw

@+p:String -> @+s:String -> @ok:Bool -> Maybe<&1, Pair(String, String)>

Exact string prefix; value is the matched prefix, rest is the suffix.

def Parse.string source · line 121 · raw

@+p:String -> @+s:String -> Maybe<&1, Pair(String, String)>

def Parse.optional.cont source · line 155 · raw

@-A:Type -> @+s:String -> @m:Maybe<&1, Pair(A, String)> -> Maybe<&1, Pair(Maybe<&1, A>, String)>

Optional: always succeeds; value is Maybe A.

def Parse.optional source · line 164 · raw

@-A:Type -> @p:Parser(A) -> @+s:String -> Maybe<&1, Pair(Maybe<&1, A>, String)>

def Parse.run source · line 170 · raw

@-A:Type -> @p:Parser(A) -> @s:String -> Maybe<&1, Pair(A, String)>

Run parser (identity application).

def Parse.run_full.rest source · line 174 · raw

@-A:Type -> @x:A -> @rest:String -> Maybe<&1, A>

Succeed only if the whole input is consumed.

def Parse.run_full.go source · line 181 · raw

@-A:Type -> @m:Maybe<&1, Pair(A, String)> -> Maybe<&1, A>

def Parse.run_full source · line 188 · raw

@-A:Type -> @p:Parser(A) -> @s:String -> Maybe<&1, A>

Templates

template Parse.satisfy source · line 87 · raw

@-pred:(@_:Char -> Bool) -> @s:String -> Maybe<&1, Pair(Char, String)>

template Parse.take_while.go source · line 127 · raw

@-pred:(@_:Char -> Bool) -> @n:Nat -> @s:String -> @acc:String -> @step:Bool -> @+h:Char -> @ok:Bool -> Pair(String, String)

take_while: one self-recursive template with Nat fuel (2 steps per char). step=False → inspect s; step=True → inspect ok (h is the candidate char). Avoids mutual template recursion (Bend: templates may only call those above).

template Parse.take_while source · line 146 · raw

@-pred:(@_:Char -> Bool) -> @+s:String -> Maybe<&1, Pair(String, String)>

Longest prefix whose chars all satisfy pred. Always succeeds (may be empty).