Skip to content

Instantly share code, notes, and snippets.

@milessabin
Created May 18, 2018 05:11
Show Gist options
  • Save milessabin/f3a7bc7cc46ef0146855b0c62774c3b6 to your computer and use it in GitHub Desktop.
Save milessabin/f3a7bc7cc46ef0146855b0c62774c3b6 to your computer and use it in GitHub Desktop.
// Current Scala 2
trait Concat[A, B] {
type Result
def apply(a: A, b: B): Result
}
object Concat {
def apply[A, B](a: A, b: B)(implicit cab: Concat[A, B]): cab.Result = cab(a, b)
implicit def hnil[B]: Concat[HNil, B] { type Result = B } = new Concat[HNil, B] {
type Result = B
def apply(a: HNil, b: B): Result = b
}
implicit def hcons[H, T, B](implicit ctb: Concat[T, B]): Concat[H :: T, B] { type Result = H :: ctb.Result } = new Concat[H :: T, B] {
type Result = H :: ctb.Result
def apply(a: H :: T, b: B): Result = a.hd :: ctb(a.tl, b)
}
// Possible compact syntax for the above ...
dep def concat[A, B](a: A, b: B): Result
case (a: HNil, b: B): B => b
case (a: H :: T, b: B): H :: ctb.Result => a.hd :: ctb
where val ctb: concat(a.tl, b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment