Scala中的类型不匹配(筛选器函数)
我是Scala的新手,尝试着关注更多的函数式编程 另一面 我正在尝试编写一个函数过滤器 以下是定义和实现:Scala中的类型不匹配(筛选器函数),scala,Scala,我是Scala的新手,尝试着关注更多的函数式编程 另一面 我正在尝试编写一个函数过滤器 以下是定义和实现: def filter[A, B](f: A => Boolean, l: List[A]): List[B] = l match { case Nil => List() case x :: xs => if (f(x)) (x: B) :: filter(f, xs) else filter(f, xs) } 使用此函数,我得到以下错误: :32:错误
def filter[A, B](f: A => Boolean, l: List[A]): List[B] = l match {
case Nil => List()
case x :: xs => if (f(x)) (x: B) :: filter(f, xs) else filter(f, xs)
}
使用此函数,我得到以下错误:
:32:错误:类型不匹配
found : x.type (with underlying type A)
required: B
case x :: xs => if (f(x)) (x: B) :: filter(f, xs) else filter(f, xs)
在此之前,我写了一个函数映射:
def map[A, B](f: A => B, l: List[A]): List[B] = l match {
case Nil => List()
case x :: xs => f(x) :: map(f, xs)
}
这实际上应用了函数f将每个列表元素从类型A转换为类型B
我对filter的错误似乎是由filter执行的函数引起的
不列出类型A的元素x,所以类型检查器认为当需要B时,我仍在构建类型A的列表。您可以看到,我试图将x指定为类型B,但没有成功。有人能确认我正确理解了这个问题吗?我怎样才能使x成为B型?我可以返回类型A的列表,但是
这是作为练习给出的函数定义,我无法更改它。您的筛选方法似乎尝试将
a
转换为B
,这不是筛选方法通常所做的A
和B
是两种不相关的类型,因此不能在它们之间进行强制转换
你可能想要这样的东西:
def filter[A](l: List[A])(f: A => Boolean): List[A] = l match {
case Nil => List()
case x :: xs => if (f(x)) x :: filter(xs)(f) else filter(xs)(f)
}
但你也可以写得简单一点:
def filter[A](l: List[A])(f: A => Boolean): List[A] =
for (x <- l if f(x)) yield x
当隐式推断
Int
类型时过滤器
不会转换列表中的元素,它只会删除谓词返回的元素false
。您只需删除类型参数B
,并将返回类型更改为List[A]
。那么,您是否认为方法声明是错误的,因为如果通过测试,筛选只是从列表中选择值,即,如果我托管类型A,则筛选函数检索类型B元素毫无意义?我认为,由于我对列表元素不做任何处理,那么B就变成了A,也就是说,如果我有list[Integer],那么即使我有list[B],那么B也会是Integer。在这种情况下,scala不会推断出B=A
。此外,事实并非如此。您的过滤器可以称为filter[Int,String]
,这是完全正确的。毕竟你可以用map
,为什么不能用filter
?是的,如果您查看scala库中的filter
,它会更复杂(请参见TraversableLike
)。它返回Repr
类型,但不返回TraversableLike
。这样做的目的是,如果调用了filter
,任何实现TraversableLike
的东西都可以返回self-type。因此,当调用filter
时,List
返回List
,而不是TraversableLike
谢谢,将检查所有这些。
filter(List(1, 3, 5, 7))(_ > 4)