gpt4 book ai didi

scala - 将函数的隐式转换链接到泛型类

转载 作者:行者123 更新时间:2023-12-05 00:16:25 25 4
gpt4 key购买 nike

我有以下代码应该采用函数 A => Boolean (输入类型的泛型)并将其转换为泛型特征 Y[A]通过链式隐式转换:

val f: Int => Boolean = ???

trait X[A] {
def m1: Unit
}
implicit def toX[A](f: A => Boolean): X[A] = ???
f.m1 // Works

trait Y[A] {
def m2: Unit
}
implicit def toY[T, A](x: T)(implicit toX: T => X[A]): Y[A] = ???
f.m2 // Won't compile

不幸的是,最后一行不会编译。

执行以下任何一项更改就足以使代码编译:
  • 车削X非通用
  • 车削Y非通用
  • 用输出类型上的泛型函数替换源类型(输入类型上的泛型函数)( Int => A )
  • 将源类型替换为其他泛型类型,例如 Option[A] , Seq[A]Array[A]

  • 基于此,我的结论是隐式转换链将不起作用,因为源类型(输入类型上的泛型函数)是泛型和逆变的 中间类型和目标类型( X[A]Y[A] )是通用的。

    关于如何解决这个问题的任何想法?

    更新:最终代码缩进处理,不仅将函数作为源类型处理,还可以处理其他类型( Option[A]Seq[A]A 等)。为了实现这一点,我们的想法是拥有 toX 的版本。将这些类型中的每一种转换为 X[A] 的函数.那么只有一个版本 toY是需要的。

    最佳答案

    我想我有一个解决你的问题的方法,看看下面的代码:

    val f: Int => Boolean = _ => true

    trait X[A] {
    def m1: Unit
    }
    implicit def funcToX[A](f: A => Boolean): X[A] = new X[A] {
    override def m1: Unit = println("Hello x")
    }
    f.m1 // Works

    trait Y[A] {
    def m2: Unit
    }
    implicit def toY[T[_,_], A](x: T[A, Boolean])(implicit toX: T[A, Boolean] => X[A]): Y[A] = new Y[A] {
    override def m2: Unit = {
    x.m1
    println("Hello y")
    }
    }
    f.m2 // now works

    我在这里使用更高级的类型语法。这是 Scala 语言的高级功能,我没有足够的经验来正确解释它。转换 toY 应该适用于任何只接受两个类型参数的类型,(并定义了转换“toX”)。

    问题是你真的需要转换 toY 才能在参数 T 上通用吗?也许它接受函数作为参数就足够了:
    implicit def toY[A](x: A => Boolean)(implicit toX: (A => Boolean) => X[A]) = ???

    你可以阅读更多关于更高级的类型,例如这篇文章:

    Scala: Types of a higher kind

    更新

    以下问题作者要求我想出了以下解决方案:
    type SingleGenericFun[T] = T => _

    val f: SingleGenericFun[Int] = _ > 42
    val g: Int = 42

    trait X[A] {
    def m1: Unit
    }
    implicit def toX(f: SingleGenericFun[Int]): X[Int] = ???
    implicit def toX(x: Int): X[Int] = new X[Int] {
    override def m1: Unit = println(x)
    }
    f.m1 // Works

    trait Y[A] {
    def m2: Unit
    }
    implicit def toY2[T[_, _], A](x: T[A, _])(implicit toX: T[A, Boolean] => X[A]): Y[A] = new Y[A] {
    override def m2: Unit = {
    x.m1
    println("Hello y!")
    }
    }
    implicit def toY0[A](x: A)(implicit toX: A => X[A]): Y[A] = new Y[A] {
    override def m2: Unit = {
    x.m1
    println("Hello y!")
    }
    }
    implicit def toY1[T[_], A](x: T[A])(implicit toX: T[A] => X[A]): Y[A] = new Y[A] {
    override def m2: Unit = {
    x.m1
    println("Hello y")
    }
    }
    g.m2
    f.m2 // Compile

    它仍然不是最好的解决方案,因为需要提供 3 种(甚至更多)方法在技术上做同样的事情,我不知道如何泛化它,也不知道它是否可能。

    关于scala - 将函数的隐式转换链接到泛型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41771776/

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