Scala 类型检查
Scala type check
如何进行此类型检查?
trait Test[A] {
type Output = A
def get: Iterable[A]
def check(a: A): Boolean
}
object A {
def fs: List[Test[_]] = ???
def test = for{f <- fs
a <- f.get
if f.check(a)} println(a)
}
它抱怨
<console>:12: error: type mismatch;
found : a.type (with underlying type _)
required: _
if f.check(a)} println(a)
尝试 #1(失败)
object A {
def fs: List[Test[_]] = ???
def test = for{f <- fs
a <- f.get
if f.check(a.asInstanceOf[f.Output])} println(a)
}
但后来我遇到了同样的问题:
<console>:12: error: type mismatch;
found : f.Output
(which expands to) _
required: _
if f.check(a.asInstanceOf[f.Output])} println(a)
尝试 #2(失败)
了解了一些存在类型后,我正在尝试替换下划线 -- 在测试级别,因为并非所有 A 都相同
object A {
def fs: List[Test[A] forSome { type A }] = ???
def test = for{f <- fs
a <- f.get
if f.check(a)} println(a)
}
它抱怨:
<console>:12: error: type mismatch;
found : a.type (with underlying type A)
required: A
if f.check(a)} println(a)
如何摆脱这种噩梦?
解决方案是将存在类型推入。
object A {
def fs: List[Test[A forSome { type A }]] = ???
def test = for{f <- fs
a <- f.get
if f.check(a)} println(a)
}
结果成功了。
基本问题是 Scala 编译器没有注意到存在性隐藏的类型必须相同。
有两种解决方案:
创建一个同时调用 get
和 check
的方法:
object A {
private def getChecked[A](f: Test[A]) = f.get.withFilter(f.check)
def fs: List[Test[_]] = ???
def test = for { f <- fs; a <- getChecked(f) } println(a)
使用类型变量模式为存在命名。不幸的是,这在 for
中似乎不起作用,因此您需要先将其脱糖:
// equivalent to your initial code
def test = fs.flatMap { f => f.get.withFilter { a => f.check(a) } }.
foreach { a => println(a) }
// with a type variable
def test = fs.flatMap { case f: Test[x] => f.get.withFilter { a => f.check(a) } }.
foreach { a => println(a) }
如何进行此类型检查?
trait Test[A] {
type Output = A
def get: Iterable[A]
def check(a: A): Boolean
}
object A {
def fs: List[Test[_]] = ???
def test = for{f <- fs
a <- f.get
if f.check(a)} println(a)
}
它抱怨
<console>:12: error: type mismatch;
found : a.type (with underlying type _)
required: _
if f.check(a)} println(a)
尝试 #1(失败)
object A {
def fs: List[Test[_]] = ???
def test = for{f <- fs
a <- f.get
if f.check(a.asInstanceOf[f.Output])} println(a)
}
但后来我遇到了同样的问题:
<console>:12: error: type mismatch;
found : f.Output
(which expands to) _
required: _
if f.check(a.asInstanceOf[f.Output])} println(a)
尝试 #2(失败)
了解了一些存在类型后,我正在尝试替换下划线 -- 在测试级别,因为并非所有 A 都相同
object A {
def fs: List[Test[A] forSome { type A }] = ???
def test = for{f <- fs
a <- f.get
if f.check(a)} println(a)
}
它抱怨:
<console>:12: error: type mismatch;
found : a.type (with underlying type A)
required: A
if f.check(a)} println(a)
如何摆脱这种噩梦?
解决方案是将存在类型推入。
object A {
def fs: List[Test[A forSome { type A }]] = ???
def test = for{f <- fs
a <- f.get
if f.check(a)} println(a)
}
结果成功了。
基本问题是 Scala 编译器没有注意到存在性隐藏的类型必须相同。
有两种解决方案:
创建一个同时调用
get
和check
的方法:object A { private def getChecked[A](f: Test[A]) = f.get.withFilter(f.check) def fs: List[Test[_]] = ??? def test = for { f <- fs; a <- getChecked(f) } println(a)
使用类型变量模式为存在命名。不幸的是,这在
for
中似乎不起作用,因此您需要先将其脱糖:// equivalent to your initial code def test = fs.flatMap { f => f.get.withFilter { a => f.check(a) } }. foreach { a => println(a) } // with a type variable def test = fs.flatMap { case f: Test[x] => f.get.withFilter { a => f.check(a) } }. foreach { a => println(a) }