Hi everyone!
I find myself using List.joinMap a lot where a filterMap would be more sensible for both readability and performance. #664 doesn't mention a filterMap, so would this be an idea people would be interested in?
Something like
filterMap : List a, (a -> [Keep b, Drop]) -> List b
So map and keep if together in one?
Exactly. It's useful when you want to filter based on what the element will be after applying the function. It helps avoid sentinel values and redundant computation. It's essentially List.keepOks but for things which aren't errors. For example:
A: [B U32, C]
withFilterMap =
List.filterMap [B 0, C, B 1] \a ->
when a is
B b -> Keep b
C -> Drop
withJoinMap =
List.joinMap [B 0, C, B 1] \a ->
when a is
B b -> [b]
C -> []
if you try rewriting these without joinMap you'll probably see why I use joinMap, and why I want a filterMap.
Makes sense
Hm, why not just use keepOks? It’s the same but with a different tag name
List.keepOks [B 0, C, B 1] \a ->
when a is
B b -> Ok b
C -> Err {}
Okay that's definitely better than joinMap haha. I will say it doesn't communicate what you're doing as well imo. keepOks means "lets do this function and only keep the ones which don't error", but when using filterMap the idea is just "we're mapping a function and disregarding some along the way" which are isomorphic but linguistically distinct enough to warrant its existence.
Yeah, that’s a good point. I think of Result as Good/Bad more than Success/Failure, but I get why the latter is the default understanding.
Either way I wouldn't say the things you want to drop from the list are either bad nor failures- they're just things you don't want.
It might also be better because you can't accidentally conflict with other types. It would be a lot clearer where my types are wrong if the compiler told me I needed a tag of [Keep a, Drop] rather than [Err {}, Ok a], especially if a is a Result itself, so the compiler would tell you that you want a [Keep [Result a e1], Drop] rather than [Err {}, Ok [Ok a, Err e1]], which probably won't be a problem when error messages improve but it's something to think about.
yeah I actually originally thought about having Keep and Drop, but I figured people would often want to use it in conjunction with things that return Result, since there are a lot of those, so I went with keepOks instead :sweat_smile:
So is the plan to not include filterMap as a builtin?
right now I'd say I'm not convinced we should add a function that does the same thing as a current function except the tags have different names.
A downside of having both is that it would create stylistic debates about which would be more appropriate to use in a given piece of code, and I think that's not a good use of people's time. :big_smile:
I suppose that's a driving force behind a lot of the language haha. At least it's good to know that keepOks is basically the same thing, which hadn't really occured to me until this thread.
Regarding List.keepOks, it sounds like there's a great opportunity for reinforcing in the tutorial that there are no truly special tags, and that functions that are result-focused can be purposed for intermediate processing as well.
or perhaps that'd be a "Thinking in Roc" advanced topics doc
Last updated: Jun 16 2026 at 16:19 UTC