Skip to content

Instantly share code, notes, and snippets.

@hooman
Last active February 16, 2018 23:23
Show Gist options
  • Save hooman/4d02e1ce78ed5cd17119628bdd4caa4a to your computer and use it in GitHub Desktop.
Save hooman/4d02e1ce78ed5cd17119628bdd4caa4a to your computer and use it in GitHub Desktop.
An operator for tuple splat of simple function arguments (up to six arguments implemented).
// An operator for tuple splat of simple function arguments (up to six arguments implemented).
// by Hooman Mehr (hooman@mac.com)
// Source released as public domain.
precedencegroup TupleSplatPrecedence {
associativity: left
higherThan: BitwiseShiftPrecedence
}
// Infix operator for on the fly tuple splat:
infix operator <~ : TupleSplatPrecedence
// Postfix operator for converting a function from simple multi-arguments, to single tuple argument:
postfix operator <~
// Infix functions for on-the-fly tuple splat into simple function arguments:
func <~ <A> (f: ()->A, tuple: () ) -> A { return f() }
func <~ <A,B,C> (f: (A,B)->C, tuple: (A,B) ) -> C { return f(tuple.0,tuple.1) }
func <~ <A,B,C,D> (f: (A,B,C)->D, tuple: (A,B,C) ) -> D { return f(tuple.0,tuple.1,tuple.2) }
func <~ <A,B,C,D,E> (f: (A,B,C,D)->E, tuple: (A,B,C,D) ) -> E { return f(tuple.0,tuple.1,tuple.2,tuple.3) }
func <~ <A,B,C,D,E,F> (f: (A,B,C,D,E)->F, tuple: (A,B,C,D,E) ) -> F { return f(tuple.0,tuple.1,tuple.2,tuple.3,tuple.4) }
func <~ <A,B,C,D,E,F,G> (f: (A,B,C,D,E,F)->G, tuple: (A,B,C,D,E,F) ) -> G { return f(tuple.0,tuple.1,tuple.2,tuple.3,tuple.4,tuple.5) }
// Postfix functions for converting functions from simple multi-arguments, to single tuple argument:
postfix func <~ <A> (f: @escaping ()->A) -> (())->A { return { (arg: ())->A in f() } }
postfix func <~ <A,B,C> (f: @escaping (A,B)->C) -> ((A,B))->C { return { (arg: (A,B))->C in f(arg.0,arg.1) } }
postfix func <~ <A,B,C,D> (f: @escaping (A,B,C)->D) -> ((A,B,C))->D { return { (arg: (A,B,C))->D in f(arg.0,arg.1,arg.2) } }
postfix func <~ <A,B,C,D,E> (f: @escaping (A,B,C,D)->E) -> ((A,B,C,D))->E { return { (arg: (A,B,C,D))->E in f(arg.0,arg.1,arg.2,arg.3) } }
postfix func <~ <A,B,C,D,E,F> (f: @escaping (A,B,C,D,E)->F) -> ((A,B,C,D,E))->F { return { (arg: (A,B,C,D,E))->F in f(arg.0,arg.1,arg.2,arg.3,arg.4) } }
postfix func <~ <A,B,C,D,E,F,G> (f: @escaping (A,B,C,D,E,F)->G) -> ((A,B,C,D,E,F))->G { return { (arg: (A,B,C,D,E,F))->G in f(arg.0,arg.1,arg.2,arg.3,arg.4,arg.5) } }
// Basic usage example:
// Sample function:
func f2(_ x: Int, _ y: Int) -> Int { return x + y }
// Normal call:
let result = f2(3,4)
// Call with tuple literal:
let result2 = f2<~(3,4)
// To make it clearer, call with tuple let-constant:
let tuple2 = (3,4)
let result3 = f2<~(tuple2) // I prefer to keep the parentheses for readability
// Convert the function to one that accepts a single tuple:
let fTuple = f2<~
let result4 = fTuple(tuple2)
// Or call with literal tuple, which is not usually desirable:
let result5 = fTuple((3,4))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment