Scala 3实现SYB的mkT函数类型推断异常求助
Scala 3中SYB框架mkT函数实现问题
我正在Scala 3中实现《Scrap Your Boilerplate》(SYB)框架,目前在实现论文中的mkT函数时遇到问题。
现有Cast特质及cast函数定义
trait Cast[A, B]: def apply(a: A): Option[B] object Cast: given cSome[A, B](using t: A =:= B): Cast[A, B] with def apply(a: A) = Some(t(a)) given cNone[A, B](using t: NotGiven[A =:= B]): Cast[A, B] with def apply(a: A) = None def cast[A, B](a: A)(using c: Cast[A, B]): Option[B] = c(a)
我的mkT实现
class MakeTransform[A] (val f: A => A) { def apply[B](b: B)(using c: Cast[A => A, B => B]): B = c(f) match { case Some(fb) => fb(b) case _ => b } } def mkT[A](f: A => A): MakeTransform[A] = MakeTransform(f)
测试情况
布尔示例(正常工作)
def not(a: Boolean): Boolean = !a mkT(not)(true) // 返回false,函数正常调用 mkT(not)('a') // 返回'a',符合预期不处理
薪资模型示例(存在问题)
先定义薪资相关类:
sealed trait Salary case class S(amt: Float) extends Salary def incS(amt: Float): Salary => Salary = { case S(a) => S(a * (1 + amt)) } val ralf: Employee = E(P("Ralf", "Amsterdam"), S(8000))
尝试调用时出现异常:
inc(.1)(S(8000)) // 返回S(8000),没有执行加薪逻辑
只有显式指定类型才能得到预期结果:
inc(.1)[Salary](S(8000)) // 返回S(8800.0),符合预期
但此时无法传入其他类型的输入,违背SYB设计初衷:
inc(.1)[Salary](ralf) // 编译失败
疑问
- 布尔示例和薪资模型示例行为不一致的原因是什么?
- 调试时如何查看编译器推断的类型参数?(调试器仅显示运行时类型)
- 问题是否和
S <: Salary而非S =:= Salary的类型关系有关?
内容的提问来源于stack exchange,提问作者anqit
相关产品推荐
相关产品推荐

