Conversation
|
As suggested in comments (was it @thomasjm asking?), the simplest solution is But yes, |
|
I tried that: encodeMethod :: Text -> VS.Vector Char
encodeMethod t =
case encodeUtf32LE t of
BS ptr len ->
runST $ VS.unsafeFreeze $
VSM.unsafeFromForeignPtr0 (castForeignPtr ptr) (len `quot` 4)))But it requires reaching into internal parts of the bytestring library* and more importantly it wasn't efficient: * I guess perhaps I could use |
src/Data/Text.hs
Outdated
|
|
||
| -- | /O(n)/ A monadic version of 'foldl'. | ||
| foldlM :: Monad m => (a -> Char -> m a) -> a -> Text -> m a | ||
| foldlM f z t = S.foldlM f z (stream t) |
There was a problem hiding this comment.
Does this implementation match Data.Foldable.foldlM, especially with regards to short-circuiting and the order of effects? Would be nice to have a test, at least for m ~ Maybe and m ~ Either.
Sigh. |
|
Whoa, thanks for doing this @noughtmare! Yes, that was me asking on StackOverflow :) |
|
I just found out that we can define foldlM k z t = T.foldr (\x go s -> k s x >>= go) pure t z This optimizes to a tight loop. |
|
I added some tests and rebased. To answer some of the questions:
We could but we don't need to. Because of Specializing
Idk about an actual benchmark, but I added an inspection test that the simplified Core is the same as
What you defined is actually already Given that the lazy I have no clue about the
Both the direct implementation and the Although it's a one-liner with |
|
@Lysxia looks good to me, thanks for wrapping it up. Could you please fix the CI job with |
|
Fixed by inspection-testing |
|
Thanks all! |
I haven't added tests or benchmarks yet, because I'm not quite sure how to do it.
Open questions:
foldlM'?Data.Text.Internal.Fusion.Commonfolds markedINLINE [0]?For motivation, see this recent stackoverflow question. There the problem is to convert a text into a vector of characters, but that requires extraneous allocation if done naively with
unfoldr Text.uncons. If afoldlMfunction were exposed like I implemented in this PR then you can write it efficiently like this:Benchmark results:
This matches the performance of an implementation I wrote that loops over the internal stream representation manually.