Scala中的类型不匹配(过滤功能)

时间:2015-09-27 18:19:15

标签: 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:错误:类型不匹配;

 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.

我对过滤器的错误似乎是由过滤器所采用的函数引起的 没有列出类型A的元素x,因此类型检查器认为我仍然在需要B时构建类型A的列表。你可以看到我试图将x指定为B类,但这是徒劳的。任何人都可以确认我正确理解问题,我怎样才能使x成为B型?我可以返回A类的列表但是 这是一个作为练习给出的函数定义,我无法改变它。

1 个答案:

答案 0 :(得分:1)

您的过滤方法似乎尝试将A转换为B,这不是过滤方法通常所做的。 AB是两种不相关的类型,因此您无法在它们之间进行投射

你会想要这样的东西:

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

请注意我已经交换了参数并将它们分开了。这样做是为了让scala的类型推断自动推断A。现在你可以这样做:

filter(List(1, 3, 5, 7))(_ > 4)

其中隐含Int类型