Last active
January 24, 2017 08:59
-
-
Save werediver/9318762f34c1316f242fcba7e43e37e2 to your computer and use it in GitHub Desktop.
Generating `curry` function in Swift 2.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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