Skip to content

Instantly share code, notes, and snippets.

@werediver
Last active January 24, 2017 08:59
Show Gist options
  • Save werediver/9318762f34c1316f242fcba7e43e37e2 to your computer and use it in GitHub Desktop.
Save werediver/9318762f34c1316f242fcba7e43e37e2 to your computer and use it in GitHub Desktop.
Generating `curry` function in Swift 2.2
// Swift 2.2
enum AccessLevel {
case Default
case Private
case Internal
case Public
var asPrefix: String {
switch self {
case Default:
return ""
case Private:
return "private "
case Internal:
return "internal "
case Public:
return "public "
}
}
}
final class Indent {
static let fourSpaces = Indent(" ")
let single: String
init(_ single: String) { self.single = single }
func times(n: Int) -> String {
return Repeat(count: n, repeatedValue: single).joinWithSeparator("")
}
}
func genCurry(n: Int, indent: Indent = .fourSpaces, accessLevel: AccessLevel = .Default, verbose: Bool = false) -> String {
let range = 1...n
let paramTypes = range
.map { "T\($0)" }
.joinWithSeparator(", ")
let genericParams = paramTypes + ", U"
let fSig = "(\(paramTypes)) -> U"
func curriedSig(paramCount: Int, offset: Int = 0) -> String {
if paramCount > 0 {
return (1...paramCount)
.map { "(T\($0 + offset))" }
.joinWithSeparator(" -> ")
+ " -> U"
} else {
return "U"
}
}
let closureOpen: String
if verbose {
closureOpen = range
.map { "{ (x\($0): T\($0)) -> \(curriedSig(n - $0, offset: $0)) in " }
.joinWithSeparator("")
} else {
closureOpen = range
.map { "{ x\($0) in " }
.joinWithSeparator("")
}
let fCall = "f(" + range
.map { "x\($0)" }
.joinWithSeparator(", ")
+ ")"
let closureClose = range
.map { _ in " }" }
.joinWithSeparator("")
let closure = closureOpen + fCall + closureClose
return accessLevel.asPrefix + "func curry<\(genericParams)>(f: \(fSig)) -> \(curriedSig(n)) {\n"
+ indent.single + "return \(closure)\n"
+ "}\n"
}
print(genCurry(2))
print(genCurry(2, verbose: true))
/*
func curry<T1, T2, U>(f: (T1, T2) -> U) -> (T1) -> (T2) -> U {
return { x1 in { x2 in f(x1, x2) } }
}
func curry<T1, T2, U>(f: (T1, T2) -> U) -> (T1) -> (T2) -> U {
return { (x1: T1) -> (T2) -> U in { (x2: T2) -> U in f(x1, x2) } }
}
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment