Have you considered making runBuilder
nonlinear, i.e. runBuilder :: Builder -> Text
? I don’t think that introduces any unsafety.
I think you’re right, but does this actually achieve anything? Isn’t a -o b
a subtype of (or at least has an injection to) a -> b
?
Indeed, if you have
f :: a ⊸ b
you can always define
g :: a -> b
g a = f a
So it is preferrable to mark linear functions as such, as clients can always downgrade to a normal arrow, if it fits their API better.
I asked because I believe that it the only place where linearity is used in the Builder module (if you make the Builder type opaque), so that part of the API could just as well be added to the existing text package. That should already give a large speedup compared to the existing lazy text builder.
Hrm:
runBuilder :: (Builder %1 -> Builder) -> Text
runBuilder :: (Builder ⊸ Builder) -> Text
…anyone for plain ol’ boring:
runBuilder :: (*Builder -> Builder) -> Text
It’s concise and {-# UnicodeSyntax #-}
-free.
Alright, last call for reviews. I’ve added a section on design.
https://hackage.haskell.org/package/text-builder-linear-0.1/candidate
Looks amazing! I would perhaps copy one or two examples from both Builder and Buffer to the README, just to complement the benchmarks; then again, they’re well visible in the modules documentation.
Thank you
In the recent developments text-linear-builder
gained a ByteString
backend: instead of threading an unpinned ByteArray
, we can make it pinned and receive a ByteString
in the end, both from the same Builder
: