scala - 在函数参数级别实现 Ad hoc 多态性(混合不同类型的参数)
问题描述
当我在 Scala 中有一个函数时:
def toString[T: Show](xs: T*): String = paths.map(_.show).mkString
以及范围内的以下类型类实例:
implicit val showA: Show[MyTypeA]
implicit val showB: Show[MyTypeB]
我可以通过toString
以下方式使用函数:
val a1: MyTypeA
val a2: MyTypeA
val stringA = toString(a1, a2)
val b1: MyTypeB
val b2: MyTypeB
val stringB = toString(b1, b2)
但我不能调用类型和toString
混合参数:MyTypeA
MyTypeB
// doesn't compile, T is inferred to be of type Any
toString(a1, b1)
是否可以重新定义toString
,以便可以混合不同类型的参数(但仅适用于Show
类型类)?
请注意,我知道 cat show interpolator 可以解决此特定示例,但我正在寻找一种也可以应用于不同情况的解决方案(例如toNumber
)。
我也知道通过.show
在将参数传递给toString
函数之前调用参数来规避问题,但我正在寻找一种方法来避免这种情况,因为它会导致代码重复。
解决方案
无形示例:
object myToString extends ProductArgs { //ProductArgs allows changing variable number of arguments to HList
//polymorphic function to iterate over values of HList and change to a string using Show instances
object showMapper extends Poly1 {
implicit def caseShow[V](implicit show: Show[V]): Case.Aux[V, String] = {
at[V](v => show.show(v))
}
}
def applyProduct[ARepr <: HList](
l: ARepr
)(
implicit mapper: Mapper[showMapper.type, ARepr]
): String = l.map(showMapper).mkString("", "", "")
}
现在让我们测试一下:
case class Test1(value: String)
case class Test2(value: String)
case class Test3(value: String)
implicit val show1: Show[Test1] = Show.show(_.value)
implicit val show2: Show[Test2] = Show.show(_.value)
println(myToString(Test1("a"), Test2("b"))) //"ab"
println(myToString(Test1("a"), Test2("b"), Test3("c"))) //won't compile since there's no instance of Show for Test3
顺便说一句,我认为toString
这不是最好的名字,因为它可能会与toString
from引起奇怪的冲突java.lang.Object
。
如果您不想弄乱无形的,我想到的另一个解决方案是创建具有不同数量的函数:
def toString[A: Show](a: A): String = ???
def toString[A: Show, B: Show](a: A, b: B): String = ???
//etc
这肯定很麻烦,但它可能是解决问题的最简单方法。
推荐阅读
- javascript - 用 JavaScript 在画布上绘制自定义光标
- ios - IOS 上的 FaceID 权限
- php - 在 WooCommerce 管理订单项目上显示产品自定义字段也适用于可变产品
- r - 具有极值的发散条形图隐藏具有小值的条形
- node.js - Github 操作 - 如何将测试覆盖率报告上传到 codecov
- python - RTSTRUCT 和 RTDOSE 文件的尺寸不匹配(Python)
- c++ - wdf windows 示例中的首选 PSM 是什么?
- javascript - 使用 mongoose 将数据插入 MongoDb
- javascript - 如何修复 Javascript 中的代码以避免 HTML 中的重复元素?
- c++ - 使用初始化列表声明动态分配数组的数组大小