You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala3:如何用类型Lambda重构带上下文绑定的MonadWriter?

Scala 3类型Lambda重构MonadWriter的正确方式

原可运行的Scala 2代码

trait Monoid[A] {
  def zero: A

  def append(a1: A, a2: A): A
}

trait Monad[F[_]] {
  def unit[A](a: A): F[A]

  def flatMap[A, B](fa: F[A])(f: A => F[B]): F[B]

  def map[A, B](fa: F[A])(f: A => B): F[B] = {
    flatMap(fa)(a => unit(f(a)))
  }
}

given monadWriter[W: Monoid]: Monad[({type l[x] = Writer[x, W]})#l] = new Monad[({type l[x] = Writer[x, W]})#l] {
  override def unit[A](a: A): Writer[A, W] =
    Writer(a, implicitly[Monoid[W]].zero)

  override def flatMap[A, B](fa: Writer[A, W])(f: A => Writer[B, W]): Writer[B, W] = {
    val fa2 = f(fa.v)
    Writer(fa2.v, implicitly[Monoid[W]].append(fa.w, fa2.w))
  }
}

编译失败的Scala 3尝试代码

given monadWriter[A, W: Monoid]: Monad[[W]=>Writer[A,W]] = new Monad[[W]=>Writer[A,W]] {
  override def unit[A](a: A): Writer[A, W] =
    Writer(a, implicitly[Monoid[W]].zero)

  override def flatMap[A, B](fa: Writer[A, W])(f: A => Writer[B, W]): Writer[B, W] = {
    val fa2 = f(fa.v)
    Writer(fa2.v, implicitly[Monoid[W]].append(fa.w, fa2.w))
  }
}

错误原因分析

  • 类型参数冲突:给定实例的类型参数W与类型Lambda内部的参数W重名,编译器无法区分固定的日志类型W和类型Lambda需要的值类型参数。
  • 多余的类型参数:monadWriter不需要额外的A类型参数,Monad[F[_]]要求F是接受单个类型参数的构造器,W作为固定的日志类型,应是给定实例的唯一类型参数。
  • 方法内类型混淆:尝试代码中方法的A参数与给定实例的A参数重名,进一步引发类型解析混乱。

正确的Scala 3重构代码

given monadWriter[W: Monoid]: Monad[[X] => Writer[X, W]] = new Monad[[X] => Writer[X, W]] {
  override def unit[A](a: A): Writer[A, W] =
    Writer(a, summon[Monoid[W]].zero)

  override def flatMap[A, B](fa: Writer[A, W])(f: A => Writer[B, W]): Writer[B, W] = {
    val fa2 = f(fa.v)
    Writer(fa2.v, summon[Monoid[W]].append(fa.w, fa2.w))
  }
}

关键修改点

  • 类型Lambda参数重命名:将类型Lambda内的参数从W改为X,避免与日志类型参数W冲突,明确X代表Writer的值类型。
  • 移除多余的A类型参数:给定实例仅保留W: Monoid作为类型参数,符合Monad[F[_]]对类型构造器的要求。
  • 替换隐式获取方式:用Scala 3推荐的summon替代implicitly,语法更简洁清晰。

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:35:28