Last active
December 13, 2020 16:10
-
-
Save DmytroMitin/0ef4c93b9a58a1f2e1d92f71fbdbfb19 to your computer and use it in GitHub Desktop.
Implicit val can't be annotated with any type so that the code compiles https://stackoverflow.com/questions/55548968/how-to-use-functors-with-scala-cats/55549231#comment97803502_55549231
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 App { | |
trait MyTrait | |
object MyTrait { | |
def materialize[A <: MyTrait](implicit m: A): A = m | |
} | |
implicit val m/*: MyTrait*/ /*: (MyTrait { | |
/*implicit*/ val x: Int | |
})*/ = new MyTrait { | |
implicit val x: Int = 10 | |
} | |
val m1 = MyTrait.materialize | |
import m1._ | |
implicitly[Int] | |
} |
@BalmungSan well, you changed the trait. This can be a third-party type class.
Usually with type classes type parameters are used as inputs and type members as outputs.
object App {
class A
class B
class C
class D
trait MyTrait[A]
object MyTrait {
def materialize[A] = new Helper[A]
class Helper[A] {
def apply[MT <: MyTrait[A]](implicit mt: MT): MT = mt
}
implicit val intMT = new MyTrait[Int] {
implicit val a: A = new A
implicit val b: B = new B
}
implicit val stringMT = new MyTrait[String] {
implicit val c: C = new C
implicit val d: D = new D
}
}
{
val m = MyTrait.materialize[Int].apply
import m._
implicitly[A]
implicitly[B]
}
{
val m = MyTrait.materialize[String].apply
import m._
implicitly[C]
implicitly[D]
}
}
import shapeless.{::, HList, HNil, Poly2}
object App {
def swap(p: Poly2)/*: Poly2*/ /*: (Poly2 {
/*implicit*/ def cse[L <: HList, A, B](implicit
ev: L <:< (A :: B :: HNil),
pCase: p.Case[B, A]
): ProductCase.Aux[L, pCase.Result]
})*/ = new Poly2 {
implicit def cse[L <: HList, A, B](implicit
ev: L <:< (A :: B :: HNil),
pCase: p.Case[B, A]
): ProductCase.Aux[L, pCase.Result] = ProductCase(l => {
val a :: b :: HNil = ev(l)
pCase(b, a)
})
}
object myPoly extends Poly2 {
implicit val intCase: Case.Aux[Int, Boolean, Long] = at((i, _) => i.toLong)
implicit val strCase: Case.Aux[String, Char, Symbol] = at((s, c) => Symbol(s + c))
}
val myPoly1 = swap(myPoly)
import myPoly1._
myPoly1(true, 10)
myPoly1('c', "ab")
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
BTW, just to propose a counter example this will work.
Better yet, use type parameters instead of type members, which aren't needed at all in this example.
-- Sincerely, Luis Miguel Mejía Suárez.