scala3 扩展方法类型参数
scala3 extension method type parameter
这是我的 scala2 代码到 scala3 的直接翻译
trait Narrow[F[_], A, B <: A: ClassTag]:
def apply(fa: F[A]): F[B]
extension [F[_], A] (fa: F[A]):
def narrow[B: ClassTag] (using op: Narrow[F, A, B]): F[B] = op(fa)
我需要在调用站点指定窄操作的类型,但是扩展方法不允许该语法。针对此限制有哪些最佳解决方法?
这样做的目的是能够缩小集合/尝试/其他任何类型中的类型。窄类型 class 将平面映射内部的任何内容,比较运行时类型,如果匹配则将 B 包装在 F 中,否则 return 空 F
trait A
trait B extends A
object A extends A
object B extends B
val bb: List[B] = List(A, A, B, B, A)
.narrow[B]
assert(bb == List(B, B))
你可以使用多态函数,如果你能处理丑陋的话:
extension [F[_], A] (fa: F[A]):
def narrow() = [B <: A] => (using op: Narrow[F, A, B]) => op(fa)
然后您可以使用 foo.narrow()[String]
调用它。 Here 在斯卡斯蒂。
narrow()
是必要的,因为没有它,类型参数将转到扩展而不是多态函数。
将来,Scala 3 可能允许类型参数直接传递给扩展内的方法,但现在,您可以继续使用 Scala 2 隐式 class 并在下一个版本后更改它:
implicit class NarrowOps[F[_], A](fa: F[A]):
def narrow[B <: A](using op: Narrow[F, A, B]) = op(fa)
旁注:您不需要在扩展中再次使用 B: ClassTag
,尽管我相信您确实需要使用绑定 B <: A
.
我无法忍受呼叫站点上的 ()
。我决定尝试使用仅带有类型参数的 apply 方法隐式转换为类型。
trait NarrowTypeClass[F[_], A, B <: A: ClassTag]:
def apply(fa: F[A]): F[B]
given [F[_], A] as Conversion[F[A], Narrowable[F, A]] = Narrowable(_)
sealed class Narrowable [F[_], A] (fa: F[A]):
def narrow[B <: A: ClassTag] (using op: NarrowTypeClass[F, A, B]): F[B] = op(fa)
这似乎可以解决问题
这是我的 scala2 代码到 scala3 的直接翻译
trait Narrow[F[_], A, B <: A: ClassTag]:
def apply(fa: F[A]): F[B]
extension [F[_], A] (fa: F[A]):
def narrow[B: ClassTag] (using op: Narrow[F, A, B]): F[B] = op(fa)
我需要在调用站点指定窄操作的类型,但是扩展方法不允许该语法。针对此限制有哪些最佳解决方法?
这样做的目的是能够缩小集合/尝试/其他任何类型中的类型。窄类型 class 将平面映射内部的任何内容,比较运行时类型,如果匹配则将 B 包装在 F 中,否则 return 空 F
trait A
trait B extends A
object A extends A
object B extends B
val bb: List[B] = List(A, A, B, B, A)
.narrow[B]
assert(bb == List(B, B))
你可以使用多态函数,如果你能处理丑陋的话:
extension [F[_], A] (fa: F[A]):
def narrow() = [B <: A] => (using op: Narrow[F, A, B]) => op(fa)
然后您可以使用 foo.narrow()[String]
调用它。 Here 在斯卡斯蒂。
narrow()
是必要的,因为没有它,类型参数将转到扩展而不是多态函数。
将来,Scala 3 可能允许类型参数直接传递给扩展内的方法,但现在,您可以继续使用 Scala 2 隐式 class 并在下一个版本后更改它:
implicit class NarrowOps[F[_], A](fa: F[A]):
def narrow[B <: A](using op: Narrow[F, A, B]) = op(fa)
旁注:您不需要在扩展中再次使用 B: ClassTag
,尽管我相信您确实需要使用绑定 B <: A
.
我无法忍受呼叫站点上的 ()
。我决定尝试使用仅带有类型参数的 apply 方法隐式转换为类型。
trait NarrowTypeClass[F[_], A, B <: A: ClassTag]:
def apply(fa: F[A]): F[B]
given [F[_], A] as Conversion[F[A], Narrowable[F, A]] = Narrowable(_)
sealed class Narrowable [F[_], A] (fa: F[A]):
def narrow[B <: A: ClassTag] (using op: NarrowTypeClass[F, A, B]): F[B] = op(fa)
这似乎可以解决问题