Add OpIntercept to allow custom types and operations#149
Add OpIntercept to allow custom types and operations#149soronpo wants to merge 9 commits intofthomas:masterfrom
Conversation
Codecov Report
@@ Coverage Diff @@
## master #149 +/- ##
==========================================
+ Coverage 91.47% 91.69% +0.21%
==========================================
Files 10 10
Lines 692 710 +18
Branches 15 15
==========================================
+ Hits 633 651 +18
Misses 59 59
Continue to review full report at Codecov.
|
|
@erikerlandson the branch is ready. Can you please check if this satisfies your usecase? |
| } | ||
| CalcCache.clearOpInterceptCalc() | ||
| cachedCalc match { | ||
| case Left(t : CalcUnknown) => |
There was a problem hiding this comment.
this is totally nitpicking, but IIUC, the convention for Either is that the Left is the "error" condition, isn't it?
There was a problem hiding this comment.
You're right. I've rarely used it in this fashion, so forgot. I'll fix.
|
@soronpo this looks very cool - so you get the |
Yes. Kinda dirty, but this will get the job done. |
|
Another cool thing is that recursive calls like Fibonacci are implicitly memoized due the caching mechanism of singleton-ops. But we are still very limited to due stack limitations. I should probably take the time to do tail-recursive refactoring as much as possible in the future. |
|
I pushed a change to the concept. I realized that the reason I had to use |
|
interesting, I couldn't figure out how to persuade Aha, I was trying to use |
|
I will be very surprised if this doesn't work for Rational, but I'll try it out to make sure |
|
Thanks. Let me know. I've pushed the last update (hopefully). I added a value return. If the return value is a singleton (literal), the implicit function for |
It should be much more simple to implement. Make sure to remove the dedicated |
|
There is a weird fail for Scala 2.11: |
|
@soronpo I played with an implementation for Rational addition, and confirmed that scala> val t = shapeless.the[Rational[1,3] + 2 + Rational[1,6]]
t: singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,singleton.ops.rational.Rational[1,3] + 2,singleton.ops.rational.Rational[1,6],singleton.ops.NP]{type OutWide = singleton.ops.rational.Rational[this.Out,this.Out]; type Out = singleton.ops.rational.Rational[this.Out,this.Out]; final val isLiteral: Boolean(false)} = $anon$1@30b7f393
scala> t.value
res13: t.Out = singleton.ops.rational$$anon$2$$anon$3@7056fb08
scala> t.value.show
res14: String = Rational(5, 2)One caveat: Getting the scala> val t = implicitly[Rational[1,3] + 2 + Rational[1,6]]
t: singleton.ops.rational.Rational[1,3] + 2 + singleton.ops.rational.Rational[1,6] = $anon$1@d402a9
scala> t.value
res11: t.Out = singleton.ops.rational$$anon$2$$anon$3@4744a330
scala> t.value.show
^
error: value show is not a member of t.Outsimilar for using scala> val t = implicitly[Id[Rational[1,3] + 2 + Rational[1,6]]]
t: singleton.ops.Id[singleton.ops.rational.Rational[1,3] + 2 + singleton.ops.rational.Rational[1,6]] = $anon$1@2fb8109b
scala> t.value
res15: t.Out = singleton.ops.rational$$anon$2$$anon$3@52d74b49
scala> t.value.show
^
error: value show is not a member of t.OutI don't think this is a deal breaker, but if there is an easy way to get the functionality of |
Yeah, I was thinking to write |
|
I'm considering changing the implementation of the internal operations and how This way we can define any operations on the typelevel on any types and arguments, and also get a term-level composed function. |
in this concept, is |
Yes. A value is optional, and where needed then it would typically depend on the actual value arguments and not summoned from thin air. |
|
I've pushed my WIP, but it will take me while to complete due to priorities. The current status is that it is impossible to combine |
See discussion on #140
For any operation/types that are not supported internally, the user can create an implicit for
OpIntercept.Aux[Op, Out]to set the operation type "value".See https://github.com/fthomas/singleton-ops/compare/master...soronpo:op_intercept?expand=1#diff-b17d5bc3066a42d6ad991f1b86cbc212 for examples.
cc @erikerlandson