Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

66%
+2 −0
Q&A How to write a function that only accepts a list of `Error string` `Results` in F# on the level of types?

I'm pretty sure the answer is "no", especially in some reasonable way. If Result was defined in some object-oriented way, i.e. as an interface with Ok and Error being implementations of that interf...

posted 4mo ago by Derek Elkins‭

Answer
#1: Initial revision by user avatar Derek Elkins‭ · 2024-01-28T00:15:39Z (4 months ago)
I'm pretty sure the answer is "no", especially in some reasonable way. If `Result` was defined in some object-oriented way, i.e. as an interface with `Ok` and `Error` being implementations of that interface, or if this was O'Caml and `Result` had been defined as a polymorphic variant, then you could do this. That said, the openness of these approaches would be inappropriate for `Result`.

Defined as a discriminated union, you can't accomplish this. However, the "right" way to handle this, which is roughly equivalent to the above approaches, but with explicit rather than implicit conversions, is not to put the strings into the `Result` type in the first place. Or, in your case, avoid boolean blindness, a term popularized (and coined?) in [this blog post](https://existentialtype.wordpress.com/2011/03/15/boolean-blindness/), but search engines will return many other more recent discussions.

Instead of discovering which case of the `Result` you have with the pattern match in `filterError` and then immediately discarding that type information by returning a `bool`, you could instead have a function `fromError : Result<'a, 'e> -> Option<'e>`, this maintains the type information. Your `filterError` function would then become `Seq.collect (fromError >> Option.toList)`.

If we adapt to the new type of `filterError`, then applying the same aversion to discarding type information to `mergeErrors` would lead to it simply being the identity function.

In general, uses of `bool` should be considered skeptically, and you should see if a `bool`-producing function can be replaced with a function that gives evidence for the result it returns. Functions like `Seq.isEmpty`, `Option.isSome`, `Option.isNone`, `Result.isError`, `Result.isOk`, etc. are almost never what you want. They and booleans in general tend to lead to implicit contracts between parts of your code. That this contract is implicit is part of the "blindness" of boolean blindness. Replacing `bool` returning functions with `Option` or `Choice` returning functions is often a solution.