Last active
January 2, 2016 19:08
-
-
Save igstan/8347852 to your computer and use it in GitHub Desktop.
This file contains 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
// The main idea with type-directed lookup is that argument values are | |
// looked up in a scope formed by appending the members in the companion | |
// object of the declared param type to the normal lexical scope. | |
// | |
// It is very similar to how implicit declarations in a companion-object | |
// are automatically addded to the implicit scope. | |
// | |
// Start reading from the `main` function. It's probably easier to follow | |
// the code. | |
object TypeDirectedLookup { | |
trait CssValue { | |
val value: String | |
} | |
case class CssColor(value: String) extends CssValue | |
case class CssProperty(name: String, value: String) { | |
override def toString = s"$name: $value" | |
} | |
case class CssName[V <: CssValue](name: String) { | |
def :=(cssValue: V): CssProperty = CssProperty(name, cssValue.value) | |
} | |
// Make some factory functions available to type-directed lookup. | |
object CssProperty { | |
val color = CssName[CssColor]("color") | |
val backgroundColor = CssName[CssColor]("background-color") | |
} | |
// Make some factory functions available to type-directed lookup. | |
object CssColor { | |
def rgb(r: Int, g: Int, b: Int): CssColor = CssColor(s"rgb($r, $g, $b)") | |
def hex(h: String): CssColor = ??? | |
def hex(h: Int): CssColor = ??? | |
} | |
// When this method will be used, values in argument position may be | |
// resolved as members of the CssProperty's companion object. | |
def div(properties: CssProperty*): String = { | |
val declarations = properties.mkString(";\n ") | |
s"""div {\n $declarations;\n}""" | |
} | |
def main(args: Array[String]): Unit = { | |
// #1 | |
div(CssProperty.backgroundColor := CssColor.rgb(0,0,0)) | |
// #2 | |
{ | |
import CssColor._ | |
import CssProperty._ | |
div(backgroundColor := rgb(0,0,0)) | |
} | |
// #3 type-directed lookup; won't compile because `color` and | |
// `backgroundColor` are not in scope. | |
div( | |
color := rgb(0,0,0), | |
backgroundColor := rgb(0,0,0) | |
) | |
// The previous call is conceptually similar to this desugaring. | |
val css = div( | |
({ import CssProperty._; color }) := ({ import CssColor._; rgb(0,255,0)}), | |
({ import CssProperty._; backgroundColor }) := ({ import CssColor._; rgb(0,0,0)}) | |
) | |
println(css) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment