【问题标题】:Scala really weird Type MismatchScala真的很奇怪类型不匹配
【发布时间】:2013-06-10 01:21:03
【问题描述】:

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

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]

编辑:

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

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)
    }

【问题讨论】:

    标签: scala


    【解决方案1】:

    你已经在原来的'dropWhile'上有类型参数A,它是f的类型。但是,您随后在内部 def 上引入了第二个类型参数,它隐藏了 A 的外部定义并限定了 XList 的类型。所以问题是A 不是同一类型!如果您删除阴影类型,一切正常(几乎没有其他更改可以让您的代码编译):

    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)
        }
    

    【讨论】:

      【解决方案2】:

      您可以只使用 foldRight 代替(我已将其简化为使用 List 而不是 XList):

      scala> def dropWhile[A](l: List[A])(f: A => Boolean): List[A] =
           | l.foldRight(List[A]())((h,t) => if (f(h)) t else h :: t)
      dropWhile: [A](l: List[A])(f: A => Boolean)List[A]
      
      scala> val l = List(1,2,3,4,5,6,5,4,3,2,1)
      l: List[Int] = List(1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1)
      
      scala> l.dropWhile(_ < 4)
      res1: List[Int] = List(4, 5, 6, 5, 4, 3, 2, 1)
      

      虽然没有回答您的found : h.type (with underlying type A) 问题:-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多