简体   繁体   中英

What is the best way to avoid clashing between two typeclass definitions in shapeless

Shapeless has a neat type class derivation mechanism that allows you to define typeclasses and get automatic derivation for any typeclass.

To use the derivation mechanism as a user of a typeclass, you would use the following syntax

import MyTypeClass.auto._

which as far as I understand it is equivalent to

import MyTypeClass.auto.derive

An issue arises when you try and use multiple typeclasses like such within the same scope. It would appear that the Scala compiler only considers the last definition of derive even though there are two versions of the function "overloaded" on their implicit arguments.

There are a couple ways I can think of to fix this. Instead of listing them here, I will mark them as answers that you can vote on to confirm sanity as well as propose any better solution.

I raised this question back in April and proposed two solutions: defining the method yourself (as you suggest):

object AutoCodecJson {
  implicit def deriveEnc[T] = macro deriveProductInstance[EncodeJson, T]
  implicit def deriveDec[T] = macro deriveProductInstance[DecodeJson, T]
}

Or using aliasing imports:

import AutoEncodeJson.auto.{ derive => deriveEnc }
import AutoDecodeJson.auto.{ derive => deriveDec }

I'd strongly suggest going with aliasing imports— Miles himself said "hadn't anticipated that macro being reused that way: not sure I approve" about the deriveProductInstance approach.

Instead of inheriting from the Companion trait, define the auto object and apply method yourself within your companion object and name them distinctively. A possible drawback to this is that two separate librairies using shapeless could end up defining a derive method with the same name and the user would end up again with a situation where he cannot use the derivation process for both type classes within the same scope in his project.

Another possible drawback is that by dealing with the macro call yourself, you may be more sensitive to shapeless API changes.

Modify/fix the Scala compiler to accept two different methods overloaded on their implicit parameters.

Is there any reason why this is impossible in theory?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM