Introduction
With the acceptance of SE-0235 (Add Result to Standard Library), Swift added another type to the Standard Library that implements a map(_ : )
function. This is a growing pattern and builds upon the functional aspects of Swift. As such, it seems logical to formalize some of these behaviors so that we can optimize code and enhance productivity.
Proposal
This proposal is to add three operators into the Standard Library, Map (|>
), Dissolve (=>
), and Unwrap (<?
). The Map operator utilizes the Result
type to wrap transformations while deferring error handling until the end of the chain. At the end of the chain, the Unwrap operator attempts to unwrap the Result
completing the function, or the Dissolve operator forwards the result to a completion function.
Additional implementations could be added to map Array
, Optional
, and Dictionary
types with the same syntax, but wrapping and unwrapping the Result
each step would be necessary for each type.
infix operator |> : LogicalDisjunctionPrecedence
infix operator => : LogicalDisjunctionPrecedence
postfix operator <?
public func |> <Source, Target> (lhs: Source, rhs: (Source) throws -> Target) -> Result<Target, Error>
{
return Result {
try rhs(lhs)
}
}
public func |> <Source, Target> (lhs: Result<Source, Error>, rhs: (Source) throws -> Target) -> Result<Target, Error>
{
return Result {
let source = try lhs.unwrapped()
return try rhs(source)
}
}
public func => <Source> (lhs: Source, rhs: (Source) -> Void)
{
rhs(lhs)
}
public postfix func <? <Value> (lhs: Result<Value, Error>) throws -> Value
{
return try lhs.unwrapped()
}
Usage
func foo(_ : A) throws -> B {..}
func bar(_ : B) throws -> C {..}
func dissolveC(_ : Result<C, Error>) { .. }
func useDissolve(startValue: A) {
startValue
|> foo
|> bar
=> dissolveC
}
func useUnwrap(startValue: A) throws -> C {
return startValue
|> foo
|> bar <?
}