Scala 真的很奇怪类型不匹配 [英] Scala really weird Type Mismatch

查看:49
本文介绍了Scala 真的很奇怪类型不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Scala 中实现 dropWhile,但在调用f(h)"错误时出现类型不匹配,该错误表明它实际上找到了它期望的类型:

I'm trying to implement dropWhile in Scala but I get a type mismatch, on the invocation of "f(h)" error that says it actually found the type it was expecting:

def dropWhile[A](l: XList[A])(f: A => Boolean): XList[A] = {

        def dropWhile[A](toCheck: XList[A], toKeep: XList[A]) : XList[A] = toCheck match {
            case XNil => toKeep
            case Cons(h, t) if **f(h)** == false => dropWhile(tail(toCheck), Cons(h, toKeep))
            case Cons(_, Cons(t1, t2)) => dropWhile(Cons(t1, t2), toKeep)
        }

        dropWhile(l, XList[A]())
    }

错误信息:

 found   : h.type (with underlying type A)
[error]  required: A

相关代码:

sealed trait XList[+A] {}
case object XNil extends XList[Nothing]
case class Cons[+A](head: A, tail: XList[A]) extends XList[A]

这是一种编译方法 - 但获胜的答案更好,并解释了原因.

Here's a way to make it compile - but the winning answer is better and explains why as well.

def dropWhile[A](l: XList[A])(f: A => Boolean): XList[A] = {

        @tailrec
        def dropWhile[A](toCheck: XList[A], toKeep: XList[A], dropItem: A => Boolean): XList[A] = toCheck match {
            case Cons(h, XNil) if !dropItem(h) => Cons(h, toKeep)
            case Cons(h, XNil) if dropItem(h) => toKeep
            case Cons(h, t) if !dropItem(h) => dropWhile(t, Cons(h, toKeep), dropItem)
            case Cons(h, t) if dropItem(h) => dropWhile(t, toKeep, dropItem)
        }

        dropWhile(l, XList[A](), f)
    }

推荐答案

您已经在原始 'dropWhile' 上有类型参数 A,它定义了 f 的类型.但是,您随后在内部 def 上引入了第二个类型参数,它隐藏了 A 的外部定义并限定了 XList 的类型.所以问题是 A 不是同一种类型!如果您删除阴影类型,则一切正常(为了编译代码而进行的其他更改很少):

You already have type parameter A on the original 'dropWhile' which is scoping the type of f. However, you then introduce a second type parameter on the inner def which shadows the outer definition of A and scopes the type of the XList. So the problem is that the A are not the same type! If you remove the shadowed type, it all works (few other changes made to get your code to compile):

def dropWhile[A](l: XList[A])(f: A => Boolean): XList[A] = {
        def dropWhile(toCheck: XList[A], toKeep: XList[A]) : XList[A] = toCheck match {
            case XNil => toKeep
            case Cons(h, t) if f(h) == false => dropWhile(t, Cons(h, toKeep))
            case Cons(_, Cons(t1, t2)) => dropWhile(Cons(t1, t2), toKeep)
        }
        dropWhile(l, XNil)
    }

这篇关于Scala 真的很奇怪类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆