Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala中的类型不匹配(筛选器函数)_Scala - Fatal编程技术网

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:错误

我是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:错误:类型不匹配

 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)