我是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类的列表但是 这是一个作为练习给出的函数定义,我无法改变它。
答案 0 :(得分:1)
您的过滤方法似乎尝试将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
请注意我已经交换了参数并将它们分开了。这样做是为了让scala的类型推断自动推断A
。现在你可以这样做:
filter(List(1, 3, 5, 7))(_ > 4)
其中隐含Int
类型