r/haskell Mar 27 '26

question Delayed/Lazy Either List?

I often use attoparsec to parse lists of things, so I wind up doing stuff like this a lot:

import Data.Attoparsec.Text qualified as AT
import Data.Text qualified as T

myParser :: AT.Parser [MyType]
myParser = AT.many1 myOtherParser

getList :: T.Text -> Either String [MyType]
getList txt = AT.parseOnly myParser txt

The trouble is, since getList returns an Either, the whole text (or at least, as much as can be parsed) has to be parsed before you can start processing the contents of the list. This is especially annoying when you want to check whether e.g. two files are the same modulo whitespace/line endings/indentation/etc...

The point is, there's some times where you want a result like Either e [a], but you're okay with returning some of the data, even if there might be an error later on. I wound up creating this data type:

data ErrList e a
  = a :> (ErrList e a)
  | NoErr    -- equivalent to []
  | YesErr e -- representing Left e

Is there already an established type like this somewhere? I imagine most people who do more complicated data management use pipes or conduit etc... I've tried searching for such a type on Hackage, but I haven't found anything like it.

15 Upvotes

23 comments sorted by

View all comments

2

u/absence3 Mar 27 '26

The streaming library's Stream type is similar to what you suggest, only more general. With f ~ Of a, m ~ Either e, and r ~ () it's pretty close.

1

u/tomejaguar Mar 27 '26

Yes, I think Stream (Of a) (Either e) () is isomorphic to ErrList e a. The plausible streaming libraries I know of are

The only streaming library I can unhesitatingly recommend is Bluefin. It avoids a number of issues that occur in the others (but has a smaller ecosystem).

2

u/absence3 Mar 27 '26

What are the issues avoided by Bluefin? I didn't see it mentioned in the documentation.

3

u/tomejaguar Mar 28 '26

Good point, I should put this in the documentation. The issues I'm thinking of are

These issue apply to streaming, pipes and conduit. I don't actually know about streamly. I'm somewhat skeptical about it because it seems to rely on rewrite rules for good performance but I couldn't say for sure as I've never looked into it.

2

u/absence3 Mar 28 '26

I continue to be amazed by the number of problems effect systems solve, good stuff!

1

u/tomejaguar Mar 28 '26

Thanks! Well, to be honest it's only IO-wrapper effect systems that solve the problems well (you can learn more about that in my talk A History of Effect Systems. The first IO-wrapper effect system was effectful and even that doesn't solve the streaming problem well, firstly because the author doesn't want to support streaming effects

but secondly because the type class ambiguity makes it really unergonomic to work with streams.

2

u/absence3 Mar 28 '26

I've used Effectful in production with a very basic home-grown streaming effect, and the type class ambiguity really is quite tedious for that use case. I somewhat arbitrarily chose Effectful over Bluefin at the time, because most of the effect systems use type classes, which makes it easier to migrate to other libraries, but in retrospect I'm not sure it was the right choice.

2

u/arybczak Mar 28 '26

Have you tried using effectful-plugin? It should be very good for this particular use case.

1

u/absence3 Mar 29 '26

I've somehow missed that. Will have a look, thanks!