【问题标题】:Scala implicit generic type auto inferenceScala 隐式泛型类型自动推断
【发布时间】:2020-10-12 01:50:38
【问题描述】:

我想构建一个转换方法以通过构建器输出特定类型,但根据情况,最后一个是否采用隐式位置会修改泛型类型自动推断。我很乐意了解更多有关的好奇行为。

trait Wrap[A]

trait Toto[A, W <: Wrap[A]] {

    def fail[A2, W2 <: Wrap[A2], T2 <: Toto[A2, W2]](f: W => W2)(implicit builder: Builder[A2, W2, T2]): T2
    def works[A2, W2 <: Wrap[A2], T2 <: Toto[A2, W2]](f: W => W2, builder: Builder[A2, W2, T2]): T2
}

trait Builder[A, W <: Wrap[A], T <: Toto[A, W]]


type A1
type W1 <: Wrap[A1]
type A2
type W2 <: Wrap[A2]
type T2 <: Toto[A2, W2]

val t1: Toto[A1, W1]
implicit val builder: Builder[A2, W2, T2]
val f: W1 => W2


t1.fail(f) // inferred type arguments [Nothing, W2, Nothing] do not conform to method fail's type parameter
    
t1.fail(f)(builder) // inferred type arguments [Nothing, W2, Nothing] do not conform to method fail's type parameter
/**
 * [error]  found   : Test.this.W1 => Test.this.W2
 * [error]  required: Test.this.W1 => W2
 */

 t1.works(f, builder) // compiles



【问题讨论】:

标签: scala type-inference implicit


【解决方案1】:

事情不是隐含的。如果你用两个参数列表重写works

def works1[A2, W2 <: Wrap[A2], T2 <: Toto[A2, W2]](f: W => W2)(builder: Builder[A2, W2, T2]): T2

这也行不通。如果f 和builder 在同一个参数列表中,那么在

t1.works(f, builder)

A2, W2, T2 被推断出来,但如果f 在第一个参数列表中,builder 在第二个参数列表中,则在

t1.works1(f)(builder)
//          ^
//         here

从第一个参数列表f 中,只有W2 被正确推断,所以A2 和T2 被推断为Nothing,然后在第二个参数列表的类型检查期间为时已晚返回并修复推理,但失败了。

Scala type inference and multiple arguments list

Type inference with type aliases and multiple parameter list function

Scala - infer type parameters

所以如果你想使用隐式builder(然后你不能使用单参数列表)尝试重写你的代码。尝试用隐式约束替换类型边界(这会改变类型推断的顺序),然​​后你必须用抽象类替换特征,以便它们可以具有隐式参数

trait Wrap[A]

abstract class Toto[A, W](implicit ev: W <:< Wrap[A]) { 
  def fail1[A2, W2, T2](f: W => W2)(implicit builder: Builder[A2, W2, T2], ev1: W2 <:< Wrap[A2], ev2: T2 <:< Toto[A2, W2]): T2
}

abstract class Builder[A, W, T](implicit ev: W <:< Wrap[A], ev1: T <:< Toto[A, W])

t1.fail1(f) //compiles

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-29
    • 2023-03-08
    • 2017-09-08
    • 2013-06-04
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 2015-08-07
    相关资源
    最近更新 更多