Consider a functions whose purpose is to ensure that N bytes are available in the builder:
The text library calls this ensureFree and has a rewrite rule for it:
"ensureFree/ensureFree" forall a b .
append (ensureFree a) (ensureFree b) = ensureFree (max a b)
I don't actually care about this rewrite rule though. I care about another one, one that text doesn't try to do, and I don't know if it was just an oversight or if there is a fundamental problem here. Any builder that can very quickly determine the maximum amount of space it needs can be rewritten to use ensure and an unsafe non-length-checking variant. For example:
copy :: Bytes -> Builder
copy b = ensure (Bytes.length b) <> noLengthCheckCopy b
With two calls to copy and then right phase restrictions on inlining, we should see:
copy a <> copy b
==> inlines to
(ensure (Bytes.length a) <> noLengthCheckCopy a) <> (ensure (Bytes.length b) <> noLengthCheckCopy b)
==> rewrite rule on ensure
ensure (Bytes.length a + Bytes.length b) <> (noLengthCheckCopy a <> noLengthCheckCopy b)
This should work not just for copy but also for fromBounded.
Consider a functions whose purpose is to ensure that N bytes are available in the builder:
The
textlibrary calls thisensureFreeand has a rewrite rule for it:I don't actually care about this rewrite rule though. I care about another one, one that
textdoesn't try to do, and I don't know if it was just an oversight or if there is a fundamental problem here. Any builder that can very quickly determine the maximum amount of space it needs can be rewritten to useensureand an unsafe non-length-checking variant. For example:With two calls to
copyand then right phase restrictions on inlining, we should see:This should work not just for
copybut also forfromBounded.