import scala.
language.
{higherKinds, implicitConversions
}
}
trait CounterOps
[C
<: Counter
] { }
class MutableCounterOps
(counter
: MutableCounter
) extends CounterOps
[MutableCounter
] { counter.value += 1
counter
}
}
implicit def counterToOps
(counter
: MutableCounter
): MutableCounterOps
= new MutableCounterOps
(counter
) }
class ImmutableCounterOps
(counter
: ImmutableCounter
) extends CounterOps
[ImmutableCounter
] { ImmutableCounter(counter.value + 1)
}
implicit def counterToOps
(counter
: ImmutableCounter
): ImmutableCounterOps
= new ImmutableCounterOps
(counter
) }
class EchoingCounterOps
[C
<: Counter
]( baseCounterOpsProvider: C => CounterOps[C],
counter: C)
println("Counting from: " + counter.value)
baseCounterOpsProvider(counter).count()
}
}
trait EchoingCounterOpsProvider
[C
<: Counter
] { }
def compose
[C
<: Counter, CO
<: CounterOps
[C
]]( baseCounterOpsProvider: C => CO): EchoingCounterOpsProvider[C] = {
new EchoingCounterOpsProvider
[C
] { new EchoingCounterOps
(baseCounterOpsProvider, counter
) }
}
}
def main
(args
: Array
[String
]): Unit
= { println("Echoing mutable...")
echoingMutable()
println("Echoing immutable...")
echoingImmutable()
}
def echoingMutable
(): Unit
= { val composed
= EchoingCounterOps.
compose(MutableCounterOps.
counterToOps)
val counter
= new MutableCounter
(3) println("New value: " + counter.count().count().count().value)
println("Retained value: " + counter.value)
}
def echoingImmutable
(): Unit
= { val composed
= EchoingCounterOps.
compose(ImmutableCounterOps.
counterToOps)
val counter
= ImmutableCounter
(3) println("New value: " + counter.count().count().count().value)
println("Retained value: " + counter.value)
}
}
aW1wb3J0IHNjYWxhLmxhbmd1YWdlLntoaWdoZXJLaW5kcywgaW1wbGljaXRDb252ZXJzaW9uc30KCnRyYWl0IENvdW50ZXIgewogIGRlZiB2YWx1ZTogSW50Cn0KCmNsYXNzIE11dGFibGVDb3VudGVyKHZhciB2YWx1ZTogSW50KSBleHRlbmRzIENvdW50ZXIKCmNhc2UgY2xhc3MgSW1tdXRhYmxlQ291bnRlcih2YWx1ZTogSW50KSBleHRlbmRzIENvdW50ZXIKCnRyYWl0IENvdW50ZXJPcHNbQyA8OiBDb3VudGVyXSB7CiAgZGVmIGNvdW50KCk6IEMKfQoKY2xhc3MgTXV0YWJsZUNvdW50ZXJPcHMoY291bnRlcjogTXV0YWJsZUNvdW50ZXIpCiAgICBleHRlbmRzIENvdW50ZXJPcHNbTXV0YWJsZUNvdW50ZXJdIHsKICBvdmVycmlkZSBkZWYgY291bnQoKTogTXV0YWJsZUNvdW50ZXIgPSB7CiAgICBjb3VudGVyLnZhbHVlICs9IDEKICAgIGNvdW50ZXIKICB9Cn0KCm9iamVjdCBNdXRhYmxlQ291bnRlck9wcyB7CiAgaW1wbGljaXQgZGVmIGNvdW50ZXJUb09wcyhjb3VudGVyOiBNdXRhYmxlQ291bnRlcik6IE11dGFibGVDb3VudGVyT3BzID0KICAgIG5ldyBNdXRhYmxlQ291bnRlck9wcyhjb3VudGVyKQp9CgpjbGFzcyBJbW11dGFibGVDb3VudGVyT3BzKGNvdW50ZXI6IEltbXV0YWJsZUNvdW50ZXIpCiAgICBleHRlbmRzIENvdW50ZXJPcHNbSW1tdXRhYmxlQ291bnRlcl0gewogIG92ZXJyaWRlIGRlZiBjb3VudCgpOiBJbW11dGFibGVDb3VudGVyID0KICAgIEltbXV0YWJsZUNvdW50ZXIoY291bnRlci52YWx1ZSArIDEpCn0KCm9iamVjdCBJbW11dGFibGVDb3VudGVyT3BzIHsKICBpbXBsaWNpdCBkZWYgY291bnRlclRvT3BzKGNvdW50ZXI6IEltbXV0YWJsZUNvdW50ZXIpOiBJbW11dGFibGVDb3VudGVyT3BzID0KICAgIG5ldyBJbW11dGFibGVDb3VudGVyT3BzKGNvdW50ZXIpCn0KCmNsYXNzIEVjaG9pbmdDb3VudGVyT3BzW0MgPDogQ291bnRlcl0oCiAgICBiYXNlQ291bnRlck9wc1Byb3ZpZGVyOiBDID0+IENvdW50ZXJPcHNbQ10sCiAgICBjb3VudGVyOiBDKQogICAgZXh0ZW5kcyBDb3VudGVyT3BzW0NdIHsKICBvdmVycmlkZSBkZWYgY291bnQoKTogQyA9IHsKICAgIHByaW50bG4oIkNvdW50aW5nIGZyb206ICIgKyBjb3VudGVyLnZhbHVlKQogICAgYmFzZUNvdW50ZXJPcHNQcm92aWRlcihjb3VudGVyKS5jb3VudCgpCiAgfQp9CgpvYmplY3QgRWNob2luZ0NvdW50ZXJPcHMgewogIHRyYWl0IEVjaG9pbmdDb3VudGVyT3BzUHJvdmlkZXJbQyA8OiBDb3VudGVyXSB7CiAgICBpbXBsaWNpdCBkZWYgY291bnRlclRvT3BzKGNvdW50ZXI6IEMpOiBDb3VudGVyT3BzW0NdCiAgfQoKICBkZWYgY29tcG9zZVtDIDw6IENvdW50ZXIsIENPIDw6IENvdW50ZXJPcHNbQ11dKAogICAgICBiYXNlQ291bnRlck9wc1Byb3ZpZGVyOiBDID0+IENPKTogRWNob2luZ0NvdW50ZXJPcHNQcm92aWRlcltDXSA9IHsKICAgIG5ldyBFY2hvaW5nQ291bnRlck9wc1Byb3ZpZGVyW0NdIHsKICAgICAgb3ZlcnJpZGUgaW1wbGljaXQgZGVmIGNvdW50ZXJUb09wcyhjb3VudGVyOiBDKTogQ291bnRlck9wc1tDXSA9CiAgICAgICAgbmV3IEVjaG9pbmdDb3VudGVyT3BzKGJhc2VDb3VudGVyT3BzUHJvdmlkZXIsIGNvdW50ZXIpCiAgICB9CiAgfQp9CgpvYmplY3QgTWFpbiB7CiAgZGVmIG1haW4oYXJnczogQXJyYXlbU3RyaW5nXSk6IFVuaXQgPSB7CiAgICBwcmludGxuKCJFY2hvaW5nIG11dGFibGUuLi4iKQogICAgZWNob2luZ011dGFibGUoKQogICAgcHJpbnRsbigiRWNob2luZyBpbW11dGFibGUuLi4iKQogICAgZWNob2luZ0ltbXV0YWJsZSgpCiAgfQoKICBkZWYgZWNob2luZ011dGFibGUoKTogVW5pdCA9IHsKICAgIHZhbCBjb21wb3NlZCA9IEVjaG9pbmdDb3VudGVyT3BzLmNvbXBvc2UoTXV0YWJsZUNvdW50ZXJPcHMuY291bnRlclRvT3BzKQogICAgaW1wb3J0IGNvbXBvc2VkLmNvdW50ZXJUb09wcwoKICAgIHZhbCBjb3VudGVyID0gbmV3IE11dGFibGVDb3VudGVyKDMpCiAgICBwcmludGxuKCJOZXcgdmFsdWU6ICIgKyBjb3VudGVyLmNvdW50KCkuY291bnQoKS5jb3VudCgpLnZhbHVlKQogICAgcHJpbnRsbigiUmV0YWluZWQgdmFsdWU6ICIgKyBjb3VudGVyLnZhbHVlKQogIH0KCiAgZGVmIGVjaG9pbmdJbW11dGFibGUoKTogVW5pdCA9IHsKICAgIHZhbCBjb21wb3NlZCA9IEVjaG9pbmdDb3VudGVyT3BzLmNvbXBvc2UoSW1tdXRhYmxlQ291bnRlck9wcy5jb3VudGVyVG9PcHMpCiAgICBpbXBvcnQgY29tcG9zZWQuY291bnRlclRvT3BzCgogICAgdmFsIGNvdW50ZXIgPSBJbW11dGFibGVDb3VudGVyKDMpCiAgICBwcmludGxuKCJOZXcgdmFsdWU6ICIgKyBjb3VudGVyLmNvdW50KCkuY291bnQoKS5jb3VudCgpLnZhbHVlKQogICAgcHJpbnRsbigiUmV0YWluZWQgdmFsdWU6ICIgKyBjb3VudGVyLnZhbHVlKQogIH0KfQo=