gpt4 book ai didi

scala - 在嵌套多态值中使用包含泛型类型参数

转载 作者:行者123 更新时间:2023-12-02 01:55:54 26 4
gpt4 key购买 nike

是否可以仅使用不带 TypeTag 的多态函数来重写以下示例?该示例由类 A[T] 组成它有一个方法 matches返回 true当应用于 A 的实例时具有相同类型的参数 Tfalse如果此类型参数具有不同的值。然后 matches映射到 hlist lA[T]两次导致包含匹配 l 的每个项目的结果的嵌套 hlists 的 hlist对抗他人:

import scala.reflect.runtime.universe._
import shapeless._

class A[T: TypeTag]{
object matches extends Poly1 {
implicit def default[U: TypeTag] = at[A[U]]{ _ => typeOf[U] <:< typeOf[T] }
}
}

val l = new A[Int] :: new A[String] :: new A[Boolean] :: HNil

object matcher extends Poly1 {
implicit def default[T] = at[A[T]]{ a => l map a.matches }
}

l map matcher

每一项都有一个匹配项,即结果是:

(true :: false :: false :: HNil) ::
(false :: true :: false :: HNil) ::
(false :: false :: true :: HNil) :: HNil

当我尝试不使用 TypeTag 重写示例时,matches总是使用它的 no大小写并返回 false:

import shapeless._

class A[T]{
object matches extends Poly1 {
implicit def yes = at[A[T]]{_ => true}
implicit def no[U] = at[U]{_ => false}
}
}

val l = new A[Int] :: new A[String] :: new A[Boolean] :: HNil

object matcher extends Poly1 {
implicit def default[T] = at[A[T]]{ a => l map a.matches }
}

l map matcher

结果是:

(false :: false :: false :: HNil) ::
(false :: false :: false :: HNil) ::
(false :: false :: false :: HNil) :: HNil

是否可以在不使用 TypeTag 的情况下重写此示例并获得与第一种情况相同的结果?

最佳答案

看起来您真的希望能够部分应用更高阶的函数来干净利落地解决这个问题。这对于开箱即用的任何良好语法都是不可能的,但我 once wrote some code 帮助使其更容易一些(请注意,这都是 1.2.4):

import shapeless._

trait ApplyMapper[HF, A, X <: HList, Out <: HList] {
def apply(a: A, x: X): Out
}

object ApplyMapper {
implicit def hnil[HF, A] = new ApplyMapper[HF, A, HNil, HNil] {
def apply(a: A, x: HNil) = HNil
}
implicit def hlist[HF, A, XH, XT <: HList, OutH, OutT <: HList](implicit
pb: Poly.Pullback2Aux[HF, A, XH, OutH],
am: ApplyMapper[HF, A, XT, OutT]
) = new ApplyMapper[HF, A, XH :: XT, OutH :: OutT] {
def apply(a: A, x: XH :: XT) = pb(a, x.head) :: am(a, x.tail)
}
}

有关某些上下文,请参阅上面链接的答案。

这允许您编写以下内容:

class A[T]

object matches extends Poly2 {
implicit def default[T, U](implicit sub: U <:< T = null) =
at[A[T], A[U]]((_, _) => Option(sub).isDefined)
}

object mapMatcher extends Poly1 {
implicit def default[T, X <: HList, Out <: HList](
implicit am: ApplyMapper[matches.type, A[T], X, Out]
) = at[(A[T], X)] { case (a, x) => am(a, x) }
}

val l = new A[Int] :: new A[String] :: new A[Boolean] :: HNil

可能有更好的解决方案,但目前我只有一分钟的时间来回应,它按原样工作:

scala> l.zip(l mapConst l).map(mapMatcher).toList.foreach(println)
true :: false :: false :: HNil
false :: true :: false :: HNil
false :: false :: true :: HNil

随心所欲。

关于scala - 在嵌套多态值中使用包含泛型类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20050445/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com