Skip to content

Instantly share code, notes, and snippets.

@DmytroMitin
Last active December 13, 2020 16:10
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DmytroMitin/ed22c9a84d5c89a46148a073b92052da to your computer and use it in GitHub Desktop.
Save DmytroMitin/ed22c9a84d5c89a46148a073b92052da to your computer and use it in GitHub Desktop.
import shapeless.{::, HNil, Poly1, poly}
object App {
implicit object p extends Poly1 {
implicit val cse: Case.Aux[Int, String] = at(_.toString)
}
// implicit val p = new Poly1 {
// implicit val cse: Case.Aux[Int, String] = at(_.toString)
// }
def foo[A <: Poly1](implicit pp: A, c: poly.Case[A, Int :: HNil]) = ???
foo
}
@DmytroMitin
Copy link
Author

object App {
  object poly {
    trait Case[P, In] {
      type Out
      def apply(t : In): Out
    }

    object Case {
      type Aux[P, In, Out0] = Case[P, In] {type Out = Out0}
    }
  }

  trait Poly[A] {
    type Case[In] = poly.Case[this.type, In]
    object Case {
      type Aux[In, Out0] = Case[In] {type Out = Out0}
      def at[In, Out0](f: In => Out0): Aux[In, Out0] = new Case[In] {
        type Out = Out0
        override def apply(x: In): Out0 = f(x)
      }
    }

    def apply[In](x: In)(implicit cse: Case[In]): cse.Out = cse(x)
  }

  implicit object intPoly extends Poly[Int] {
    implicit val stringCase: Case.Aux[String, Boolean] = Case.at(_ => true)
    implicit val charCase: Case.Aux[Char, Boolean] = Case.at(_ => false)
  }

  implicit object doublePoly extends Poly[Double] {
    implicit val stringCase: Case.Aux[String, Boolean] = Case.at(_ => false)
    implicit val charCase: Case.Aux[Char, Boolean] = Case.at(_ => true)
  }

//  implicit val intPoly = new Poly[Int] {
//    implicit val stringCase: Case.Aux[String, Boolean] = Case.at(_ => true)
//    implicit val charCase: Case.Aux[Char, Boolean] = Case.at(_ => false)
//  }
//
//  implicit val doublePoly = new Poly[Double] {
//    implicit val stringCase: Case.Aux[String, Boolean] = Case.at(_ => false)
//    implicit val charCase: Case.Aux[Char, Boolean] = Case.at(_ => true)
//  }

  def foo[A, P <: Poly[A], In](a: A, x: In)(implicit p: P, c: poly.Case[P, In]) = ???

  foo(1, "a")
  foo(1, 'a')
  foo(1.0, "a")
  foo(1.0, 'a')
}

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