Created
March 20, 2017 22:54
-
-
Save zainab-ali/bb21f798b87340692760277484158be1 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
object gist { | |
import shapeless._ | |
trait Semigroup[A] { | |
def combine(a0: A, a1: A): A | |
} | |
implicit final class SemigroupCombineOps[A](a0: A)(implicit S: Semigroup[A]) { | |
def combine(a1: A): A = S.combine(a0, a1) | |
} | |
//The HList here is a meta tag - we never instantiate it. The order of elements in the hlist isn't important. | |
case class Quantity[H <: HList](value: Double) | |
object Quantity { | |
implicit def quantitySemigroup[H <: HList]: Semigroup[Quantity[H]] = new Semigroup[Quantity[H]] { | |
def combine(q0: Quantity[H], q1: Quantity[H]): Quantity[H] = Quantity[H](q0.value + q1.value) | |
} | |
} | |
object ThisCantWork { | |
type Foo | |
type Bar | |
//for all intents and purposes, these represent the same thing. Physically, we should be able to combine them. | |
val q0: Quantity[Foo :: Bar :: HNil] = Quantity(1.0) | |
val q1: Quantity[Bar :: Foo :: HNil] = Quantity(2.0) | |
//of course, we can't combine them - the types are different | |
//q0 combine q1 | |
} | |
object WorkAround { | |
import shapeless.ops.hlist.Align | |
//we can safely cast, since both hlists have the same elements | |
implicit def realignQuantity[A <: HList, B <: HList](q: Quantity[A])(implicit ev: Align[A, B]): Quantity[B] = q.asInstanceOf[Quantity[B]] | |
type Foo | |
type Bar | |
val q0: Quantity[Foo :: Bar :: HNil] = Quantity(1.0) | |
val q1: Quantity[Bar :: Foo :: HNil] = Quantity(2.0) | |
q0 combine q1 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment