Created
June 11, 2016 21:04
-
-
Save metasim/916bb473aed5b7e6daea83ebf87037d1 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| import scala.reflect.runtime.universe._ | |
| sealed trait not[-A] {} | |
| type union[A,B] = { | |
| type prove[Z] = not[not[Z]] <:< not[not[A] with not[B]] | |
| } | |
| type Tagged[U] = { type Tag = U } | |
| type @@[T, U] = T with Tagged[U] | |
| case class Transformed(state: Boolean, value: String) | |
| trait ADomain | |
| trait BDomain | |
| // https://coderwall.com/p/l-plmq/adding-semantic-to-base-types-parameters-in-scala | |
| type A = String @@ ADomain | |
| type B = String @@ BDomain | |
| implicit class TaggedInt(val s: String) extends AnyRef { | |
| def asA = s.asInstanceOf[A] | |
| def asB = s.asInstanceOf[B] | |
| } | |
| type ATransformed = A ⇒ Transformed | |
| type BTransformed = B ⇒ Transformed | |
| type AtoB = A ⇒ B | |
| type BtoA = B ⇒ A | |
| implicit class EnrichA(a: AtoB) { | |
| def grow(n: Int): BtoA = (a andThen (_ * n)).asInstanceOf[BtoA] | |
| } | |
| implicit class EnrichB(a: BtoA) { | |
| def shrink(n: Int): AtoB = (a andThen (_ drop n)).asInstanceOf[AtoB] | |
| } | |
| implicit class EnrichAorB[T: union[AtoB, BtoA]#prove: TypeTag](aorb: T) { | |
| val tpe = implicitly[TypeTag[T]] | |
| def trans(b: Boolean) = (aorb match { | |
| case f: AtoB @unchecked if tpe == typeTag[AtoB] ⇒ f andThen {s ⇒ Transformed(b, if(b) s.toUpperCase else s.toLowerCase)} | |
| case f: BtoA @unchecked if tpe == typeTag[BtoA] ⇒ f andThen {s ⇒ Transformed(b, if(!b) s.toUpperCase else s.toLowerCase)} | |
| }).asInstanceOf[String ⇒ Transformed] | |
| } | |
| val Start: AtoB = (a: A) ⇒ a.asInstanceOf[B] | |
| val valid1 = Start grow 3 shrink 2 trans true | |
| val valid2 = Start grow 3 shrink 2 grow 2 trans true | |
| //val invalid1 = Start shrink 2 grow 2 | |
| //val invalid2 = Start grow 2 grow 3 | |
| valid1("blah".asA) | |
| valid2("boo".asA) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment