Skip to content

Instantly share code, notes, and snippets.

View propensive's full-sized avatar

Jon Pretty propensive

View GitHub Profile
@propensive
propensive / outcomes.scala
Last active August 29, 2015 14:15
Using TMaps for error handling
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.6.0_27).
Type in expressions to have them evaluated.
Type :help for more information.
// Import the Rapture modules we need
scala> import rapture._, uri._, codec._, io._, fs._, core._, csv._
import rapture._
import uri._
import codec._
import io._
@propensive
propensive / customerror.scala
Last active August 29, 2015 14:15
Providing custom type mismatch errors in Scala
import language.experimental.macros
import language.implicitConversions
import scala.reflect.macros._
// We are going to provide a custom error message for when users use the wrong variant of some
// type, `Foo`. Note that `Foo` needs to be invariant or contravariant in its type parameter!
case class Foo[T]()
object Foo {
implicit def reportError[T, U](value: Foo[T]): Foo[U] = macro Macros.reportErrorMacro[T, U]
}
@propensive
propensive / recursive.scala
Last active August 29, 2015 14:14
Recursive extraction in Rapture JSON
// Rapture imports
import rapture.json._
import jsonBackends.jawn._
// Define our AST
class Op(val opName: String) extends AnyVal { override def toString = opName }
sealed trait ExprTree
case class Ident(name: String) extends ExprTree { override def toString = name }
case class Expr(left: ExprTree, op: Op, right: ExprTree) extends ExprTree { override def toString = s"$left $op $right" }
@propensive
propensive / heteroargs.scala
Created January 31, 2015 20:03
Easy Heterogeneous Varargs in Scala
// Define the general Arg type and companion object:
import language.higherKinds, language.implicitConversions, language.existentials
object Arg { implicit def toArg[Tc[_], T: Tc](t: T): Arg[T, Tc] = Arg(t, implicitly[Tc[T]]) }
case class Arg[T, Tc[_]](value: T, typeclass: Tc[T])
// Say, for example we have a typeclass for getting the length of something, with a few instances
trait Lengthable[T] { def length(t: T): Int }
implicit val intLength = new Lengthable[Int] { def length(i: Int) = 1 }
implicit val stringLength = new Lengthable[String] { def length(s: String) = s.length }
// Define the following traits and companion object
// It's in Rapture Core (https://github.com/propensive/rapture-core) if you don't want to
trait LowPriorityDefaultsTo { implicit def fallback[T, S]: DefaultsTo[T, S] = null }
object DefaultsTo extends LowPriorityDefaultsTo { implicit def defaultDefaultsTo[T]: DefaultsTo[T, T] = null }
trait DefaultsTo[T, S]
// Then, assuming we want to specify a default for a type class like `Namer`,
case class Namer[T](name: String)
@propensive
propensive / proxies.scala
Created January 25, 2015 10:51
"Proxies" with implicits and singleton types
package proxy
import language.dynamics
abstract class Param[T] { type Type }
object Param {
def apply[T](name: String) = new Param[name.type] { type Type = T }
}
class Proxy(underlying: Map[String, Any]) extends Dynamic {
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.6.0_27).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import rapture.json._; import jsonBackends.scalaJson._
import rapture.json._
import jsonBackends.scalaJson._
scala> class SpecialInt(val i: Int) extends AnyVal
defined class SpecialInt
Welcome to Scala version 2.11.4 (OpenJDK 64-Bit Server VM, Java 1.6.0_27).
Type in expressions to have them evaluated.
Type :help for more information.
scala> case class Foo[T](name: String)
defined class Foo
scala> implicit val stringFoo = Foo[String]("String")
stringFoo: Foo[String] = Foo(String)
@propensive
propensive / strap.scala
Last active August 29, 2015 14:12
Collection.strap
Welcome to Scala version 2.10.4 (OpenJDK 64-Bit Server VM, Java 1.6.0_27).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import rapture.core._
import rapture.core._
scala> List.strap(1, Some(2), None)
res0: List[Int] = List(1, 2)
case class Instantiator[T]()
def instantiate[T](implicit inst: Instantiator[T]): T = null.asInstanceOf[T]
val x: String = instantiate
// error: could not find implicit for Instantiator[T]
implicit def inst1: Instantiator[String] = Instantiator[String]
implicit def inst2: Instantiator[Int] = Instantiator[Int]
val x: String = instantiate
// error: ambiguous implicits