나는 예를타입 생성자 추상 타입 멤버를 스칼라로 추측 할 수 있습니까?
trait F[T] { type Out }
object F {
type Aux[T, out] = F[T] { type Out = out }
}
def glhf[t, out](implicit f: F.Aux[t, out]): out = ???
이 추출 모든 종류의 (심지어 복잡한 상호 암시 적 형태 변수)에 대한 매력처럼 작동을 위해, (라 볼품) 암시 적 매개 변수의 추상 형식의 멤버를 추출하기 위해 노력하고 있습니다.
그러나 추상 형식 멤버가 형식 생성자이고 단순 형식이 아닌 경우 컴파일러는 호출 지점에서 형식 변수를 통합하지 못합니다.
이상한 컴파일 오류가있는 작은 테스트 케이스를 만들었습니다. 컴파일러 오류 자체가별로 의미가 없으므로이 컴파일러 버그 여부 궁금해? 오류 메시지 세부 사항은 코드 샘플을 참조하십시오.
여분의 메시지는 scala-2.12.4
, -Xlog-implicits
으로 컴파일되며, 문제가되는 경우는 -Ypartial-unification
입니다.
incubator/Main.scala
package incubator
object wat {
/**
* A "type class", "implicit evidence" type, etc...
*
* @tparam t just for looks, and facilitate
* the implicit resolution scenario
*/
trait fo[t] {
/**
* An abstract type member THAT IS A TYPE CONSTRUCTOR
*/
type f[_]
}
//
// Types that will be used for `fo`'s abstract type `f[_]`
//
trait F1[t]
trait F2[t]
//
// Couple of case for type class `fo`
//
trait loo
implicit object loo extends loo with fo[loo] {
type f[t] = F1[t]
}
//
trait poo
implicit object poo extends poo with fo[poo] {
type f[t] = F2[t]
}
// Double checking, this compiles
val w0 = implicitly[ fo[loo] ]
val w1 = implicitly[ fo[poo] ]
/**
* *** PROBLEM HERE ***
*
* A method call, in which the abstract TYPE CONSTRUCTOR type member
* needs to be inferred by the compiler.
*
* This fails to be implicitly resolved, because the compiler
* fails to instantiate the type parameters, (probably) because
* it is unable to infer abstract type `f`. See further below
* for the failed invocation.
*
*/
def fu0[t, in[_]](t: t)(
implicit
fo: fo[t] { type f[a] = in[a] }
): String = s"Hi $t: $fo"
// These will work fine, since we explicitly set type param `in`
val w2 = fu0[loo, F1](loo: loo)
val w3 = fu0[poo, F2](poo: poo)
// *** PROBLEM HERE ***
// The following fails to compile
val w4 = fu0(loo: loo) // type ascription for test simplification
val w5 = fu0(poo: poo) // type ascription for test simplification
//
// Error message:
//
// (notice the "type f has one type parameter, but type in has one"
// part of the error)
//
// [info] .../incubator/Main.scala:64:15: poo is not a valid implicit value for incubator.wat.fo[incubator.wat.poo]{type f[a] = in[a]} because:
// [info] type parameters weren't correctly instantiated outside of the implicit tree: inferred kinds of the type arguments (incubator.wat.poo.f[t]) do not conform to the expected kinds of the type parameters (type in).
// [info] incubator.wat.poo.f[t]'s type parameters do not match type in's expected parameters:
// [info] type f has one type parameter, but type in has one
// [info] val w5 = fu0(poo: poo) // type ascription for test simplification
// [info] ^
// [info] .../incubator/Main.scala:64:15: incubator.this.wat.poo is not a valid implicit value for incubator.wat.fo[incubator.wat.poo]{type f[a] = in[a]} because:
// [info] type parameters weren't correctly instantiated outside of the implicit tree: inferred kinds of the type arguments (incubator.wat.poo.f[t]) do not conform to the expected kinds of the type parameters (type in).
// [info] incubator.wat.poo.f[t]'s type parameters do not match type in's expected parameters:
// [info] type f has one type parameter, but type in has one
// [info] val w5 = fu0(poo: poo) // type ascription for test simplification
// [info] ^
// [error] .../incubator/Main.scala:64:15: could not find implicit value for parameter fo: incubator.wat.fo[incubator.wat.poo]{type f[a] = in[a]}
// [error] val w5 = fu0(poo: poo) // type ascription for test simplification
// [error] ^
// [error] two errors found
// [error] (compile:compileIncremental) Compilation failed
// [error] Total time: 1 s, completed Oct 22, 2017 4:48:35 PM
//
}
감사합니다,하지만 당신은 포인트가 [에서 해당 형식 매개 변수 '입니다 meniton로 _ ]'메서드의 서명에 재사용됩니다. 귀하의 솔루션은 단순히 서명에서 유형 변수를 제거합니다. 이 사용 사례를 지정하려면 질문에 명확한 설명이 필요합니다. 다시 한번 감사드립니다. –
포괄적 인 테스트 케이스를 만들 때 주석에 나를 태그 지정하십시오 :) –