Skip to content

Instantly share code, notes, and snippets.

@bmc
Last active March 27, 2017 00:40
Show Gist options
  • Save bmc/27c298579f022bf7ca2e29b3e583f7fd to your computer and use it in GitHub Desktop.
Save bmc/27c298579f022bf7ca2e29b3e583f7fd to your computer and use it in GitHub Desktop.
Attempt to embed any type in a Contextual interpolator
package org.clapper
import scala.language.implicitConversions
import contextual._
object ThingTest1 {
case class Thing(s: String)
sealed trait ThingContext extends Context
final object InString extends ThingContext
trait ThingInterpolator extends Interpolator {
type ContextType = ThingContext
type Input = String
type Output = Thing
}
object ThingInterpolator extends ThingInterpolator {
def contextualize(interpolation: StaticInterpolation): Seq[ContextType] = {
interpolation.parts.map { _ => InString }
/*
case lit @ Literal(i, s) =>
InString
case hole @ Hole(_, _) =>
InString
}
*/
}
def evaluate(interpolation: RuntimeInterpolation): Thing =
Thing(interpolation.parts.mkString)
}
implicit class ThingStringContext(sc: StringContext) {
val thing = Prefix(ThingInterpolator, sc)
}
// The following two defs (embedT and embedAnything) allow any type to
// be embedded, via its toString method. Type signatures are included
// for clarity of understanding.
private def embedT[T, C <: Context](s1: C, s2: C):
Embedder[(C, C), T, ThingInterpolator.Input, ThingInterpolator.type] =
ThingInterpolator.embed[T](
Case(s1, s2) { (t: T) => t.toString }
)
implicit def embedAnything[T]:
Embedder[(InString.type, InString.type), T,
ThingInterpolator.Input, ThingInterpolator.type] = {
embedT[T, InString.type](InString, InString)
}
}
package org.clapper
import contextual.Interpolator.Embedded
import scala.language.implicitConversions
import contextual._
object ThingTest1 {
case class Thing(s: String)
sealed trait ThingContext extends Context
final object InString extends ThingContext
trait ThingInterpolator extends Interpolator {
type ContextType = ThingContext
type Input = String
type Output = Thing
}
object ThingInterpolator extends ThingInterpolator {
def contextualize(interpolation: StaticInterpolation): Seq[ContextType] = {
interpolation.parts.map { _ => InString }
/*
case lit @ Literal(i, s) =>
InString
case hole @ Hole(_, _) =>
InString
}
*/
}
def evaluate(interpolation: RuntimeInterpolation): Thing =
Thing(interpolation.parts.mkString)
}
implicit class ThingStringContext(sc: StringContext) {
val thing = Prefix(ThingInterpolator, sc)
}
// The following two defs (embedT and embedAnything) allow any type to
// be embedded, via its toString method.
private def embedT[T, C <: Context](cases: Case[(C, C), T, ThingInterpolator.Input]*):
Embedder[(C, C), T, ThingInterpolator.Input, ThingInterpolator.type] =
ThingInterpolator.embed[T](cases: _*)
implicit def embedAnything[T]:
Embedder[(InString.type, InString.type), T,
ThingInterpolator.Input, ThingInterpolator.type] = {
embedT[T, InString.type](
Case(InString, InString) { o => o.toString }
)
}
}
@bmc
Copy link
Author

bmc commented Mar 26, 2017

Second example is slightly more general-purpose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment