Skip to content

Instantly share code, notes, and snippets.

@romainmenke
Last active March 12, 2016 09:03
Show Gist options
  • Save romainmenke/e91af1f64112af095c01 to your computer and use it in GitHub Desktop.
Save romainmenke/e91af1f64112af095c01 to your computer and use it in GitHub Desktop.
protocol Executable {
typealias Input
typealias Output
var capture : Input? { get set }
var block : Input -> Output { get set }
}
extension Executable {
func execute(input:Input) -> Output {
return block(input)
}
func execute() -> Output? {
if let capture = capture {
return block(capture)
} else {
return nil
}
}
}
struct Closure<Input,Output> : Executable {
var block : Input -> Output
var capture : Input?
init(closure: Input -> Output) {
block = closure
}
init(closure:Closure) {
block = closure.block
}
init<T>(firstLink: Input -> T, secondLink: T -> Output) {
func chainInit(input:Input) -> Output {
return secondLink(firstLink(input))
}
block = chainInit
}
init<T>(firstLink: Closure<Input,T>, secondLink: Closure<T,Output>) {
func chainInit(input:Input) -> Output {
return secondLink.execute(firstLink.execute(input))
}
block = chainInit
}
init<T>(firstLink: Input -> T, secondLink: Closure<T,Output>) {
func chainInit(input:Input) -> Output {
return secondLink.execute(firstLink(input))
}
block = chainInit
}
init<T>(firstLink: Closure<Input,T>, secondLink: T -> Output) {
func chainInit(input:Input) -> Output {
return secondLink(firstLink.execute(input))
}
block = chainInit
}
}
extension Closure {
func chain<T>(closure:Closure<Output,T>) -> Closure<Input,T> {
return Closure<Input,T>(firstLink: self, secondLink: closure)
}
func chain<T>(closure: Output -> T) -> Closure<Input,T> {
return Closure<Input,T>(firstLink: self, secondLink: closure)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment