Skip to content

Instantly share code, notes, and snippets.

View milessabin's full-sized avatar

Miles Sabin milessabin

View GitHub Profile
// See http://lampsvn.epfl.ch/trac/scala/ticket/967.
//
// Gilles' fix causes the definition of Nat to be rejected with the error
// "Parameter type in structural refinement may not refer to a type member
// of that refinement". However we can work around the problem by
// quantifying out the problematic parameter type and reinstating it via
// a generalized type constraint.
type Num = {
type Rep
@milessabin
milessabin / conversions.scala
Created June 15, 2011 14:29
Code from my talk on representing polymorphic function values using type classes at the Scala eXchange ... full blog post to follow on http://www.chuusai.com/blog.
object Tuples {
import HLists._
implicit def tuple1ToHList[A](t : Product1[A]) = new { def hlisted : A :: HNil = t._1 :: HNil }
implicit def tuple2ToHList[A, B](t : Product2[A, B]) = new { def hlisted : A :: B :: HNil = t._1 :: t._2 :: HNil }
implicit def tuple3ToHList[A, B, C](t : Product3[A, B, C]) = new { def hlisted : A :: B :: C :: HNil = t._1 :: t._2 :: t._3 :: HNil }
implicit def hListToTuple1[A](h : A :: HNil) = new { def tupled : Tuple1[A] = Tuple1(h.head) }
implicit def hListToTuple2[A, B](h : A :: B :: HNil) = new { def tupled : (A, B) = (h.head, h.tail.head) }
implicit def hListToTuple3[A, B, C](h : A :: B :: C :: HNil) = new { def tupled : (A, B, C) = (h.head, h.tail.head, h.tail.tail.head) }
@milessabin
milessabin / gist:1164885
Created August 23, 2011 11:19
Boxed lazy values
// Is this even faintly novel? The closest I've seen is
//
// http://stackoverflow.com/questions/2618891/using-lazy-evaluation-functions-in-varargs
//
// which is a bit clunky by comparison. But this is so trivial someone must have
// done it this way before.
// UPDATE:
// Thanks to the Twittersphere (@etorreborre, @pchiusano and @loverdos) for a few sightings of related things,
//
def unexpected : Nothing = sys.error("Unexpected invocation")
// Encoding for "A is not a subtype of B"
trait <:!<[A, B]
// Uses ambiguity to rule out the cases we're trying to exclude
implicit def nsub[A, B] : A <:!< B = null
implicit def nsubAmbig1[A, B >: A] : A <:!< B = unexpected
implicit def nsubAmbig2[A, B >: A] : A <:!< B = unexpected
case class ServiceId[T](id : Int)
implicit val lisServiceId =
ServiceId[android.view.LayoutInflater](Context.LAYOUT_INFLATER_SERVICE)
def service[T](implicit sid: ServiceId[T]): T = {
context.getSystemService(sid.id).asInstanceOf[T]
}
@milessabin
milessabin / gist:1705644
Created January 30, 2012 17:47
Access to companion object of Foo via implicit resolution
trait Companion[T] {
type C
def apply() : C
}
object Companion {
implicit def companion[T](implicit comp : Companion[T]) = comp()
}
object TestCompanion {
@milessabin
milessabin / gist:1819087
Created February 13, 2012 18:59
Access to companion object via implicit resolution
// See this mailing list thread for context:
// https://groups.google.com/d/topic/scala-language/ImqJuGylyi8/discussion
case class Companion[-C, T](t : T)
trait Publish[C, T] { self : T =>
implicit val companion = Companion[C, T](this)
}
trait StaticKey {
@milessabin
milessabin / gist:1907932
Created February 25, 2012 11:20
Lifting Monoid over arbitrary arity type constructors
object MonoidExamples {
import shapeless._
import HList._
trait Monoid[T]
// Boilerplate ...
trait HListed[S, L <: HList]
implicit def hl1[S[_], A] = new HListed[S[A], A :: HNil] {}
implicit def hl2[S[_, _], A, B] = new HListed[S[A, B], A :: B :: HNil] {}
@milessabin
milessabin / gist:2031481
Created March 13, 2012 20:49
Impredicative types in Scala via shapeless
// See http://research.microsoft.com/en-us/um/people/simonpj/papers/boxy/boxy-icfp.pdf
object Impredicative extends App {
import shapeless._
import TypeOperators._
object head extends (List ~> Id) {
def default[T](l : List[T]) = l.head
}
def g(o : Option[List ~> Id]) = o match {
@milessabin
milessabin / gist:2336624
Created April 8, 2012 10:59
Name this idiom. Is it novel?
// K ~?> V witnesses the existence of a natural transformation between K and V
class ~?>[K[_], V[_]] {
class λ[KT, VT] // Witness K ~?> V at a particular K[T], V[T]
}
object ~?> {
// To instantiate the first-order witness we need a value of the
// higher-kinded witness, so we depend on it implicitly
implicit def witness[K[_], V[_], T](implicit rel : K ~?> V) = new rel.λ[K[T], V[T]]