Closed oscbyspro closed 4 weeks ago
Note that this method makes it straightforward to use a single error indicator for an entire algorithm in cases where the implicit error propagation approach uses one error indicator per named entity. In the exponentiation algorithm, for example, the power and multiplier both manage an error indicator. With this approach, you can just sink all multiplication errors.
Generating the Bool
is one of the pain-points. So I'll add some static sink(_:)
too:
extension Fallible {
/// Generates an `error` indicator then combines it at the end of the `action`.
@inlinable public static func sink(_ action: (inout Bool) -> Value) -> Self { ... }
/// Generates an `error` indicator then combines it at the end of the `action`.
@inlinable public static func sink(_ action: (inout Bool) -> Self ) -> Self { ... }
}
Here's just some examples uses cases from one of my randomized multiplication tests:
let foo = Fallible<T>.sink {
lhs.plus(rhs).sink(&$0).squared()
}
let bar = Fallible<T>.sink {
let a: T = lhs.squared( ).sink(&$0)
let b: T = lhs.times(rhs).sink(&$0).times(2).sink(&$0)
let c: T = rhs.squared( ).sink(&$0)
return a.plus(b).sink(&$0).plus(c )
}
I'm not sure how easy it is to appreciate the simplicity of it vs (#117), but it's great.
I'm working on more maintainable redemption arcs. Of note, this operation scales well:
Depending on how the new approach turns out, I may revisit
mutating
methods. We'll see.Notes on Fallible/map(_:)
Fallible/map(_:)
works in simple cases but it quickly devolves into a pyramid-of-doom.