Skip to content

Instantly share code, notes, and snippets.

@dduan
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dduan/2ef19b5fc1d7ef71d70b to your computer and use it in GitHub Desktop.
Save dduan/2ef19b5fc1d7ef71d70b to your computer and use it in GitHub Desktop.
Is there a better way to linearize the following construct?
// Swift 2 Beta 2 to the rescue!
protocol A {
var b: B { get set }
}
protocol B {
func handle()
}
extension B {
func printSelf() { print("I'm \(self)") }
}
protocol M:A,B {
init(b:B)
}
struct M1: M {
var b: B
func handle() {
printSelf()
b.handle()
}
}
struct M2: M {
var b: B
func handle() {
printSelf()
b.handle()
}
}
struct B1: B {
func handle() {
printSelf()
}
}
// to avoid this nested pattern:
let p1: B = M2(b: M1(b: B1()))
func chain(ms:[M.Type], b:B) -> B {
if ms.count == 0 { return b }
return ms[0].init(b: chain(Array(ms[1..<ms.count]), b: b))
}
chain([M1.self, M2.self], b: B1()).handle()
protocol A {
var b: B { get set }
}
protocol B {}
struct M1: A, B {
var b: B
}
struct M2: A, B {
var b: B
}
struct B1: B {}
// to avoid this nested pattern:
let p1: B = M2(b: M1(b: B1()))
// one solution would be
func chain(bs: [B->B], last:B) -> B {
if bs.count == 0 { return last }
return bs[0](chain(Array(bs[1..<bs.count]), last: last))
}
// now we can define equivalent of p1 in a linear way
let p2 = chain(
[
{ b -> B in M2(b: b) },
{ b -> B in M1(b: b) }
],
last: B1()
)
// is there a cleaner way?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment