首页 > 解决方案 > Why fold infers Any?

问题描述

I'm compiling with Scala 2.11.12 and this declaration:

import scala.collection.mutable.Stack
def stackToInt(stack: Stack[Int]): Int =
  stack.zipWithIndex.fold(0){ case (z: Int, (piece: Int, index: Int)) =>
    piece match {
      case 1 => (1 << index) + z
      case _ => z
    }
  }

gives:

stack.zipWithIndex.fold(0){ case (z: Int, (piece: Int, index: Int)) =>
                       ^
error: type mismatch;
        found   : Any
        required: Int

I've been dealing with stuff like this many times when writing folds in this project (first one in Scala) and I always found a different way to make it work, but maybe if I understand it I will stop hitting this wall.

标签: scalatypestype-inferencefoldtype-mismatch

解决方案


因为您需要使用foldLeft而不是折叠:

import scala.collection.mutable.Stack
def stackToInt(stack: Stack[Int]): Int =
  stack.zipWithIndex.foldLeft(0) { case (z: Int, (piece: Int, index: Int)) =>
    piece match {
      case 1 => (1 << index) + z
      case _ => z
    }
  }

斯卡蒂:https ://scastie.scala-lang.org/VzfKqHZ5QJyNPfwpLVGwSw

fold不起作用,因为它是语义的:fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1- 因此在你的情况下zipWithIndex给出(Int, Int)type 而不是 expected Int,并且函数内部返回Int- 所以最后你会看到推断类型- 和Any之间的共同祖先。(Int, Int)Int

并且foldLeft[Z](zero: Z)有推断Int,因为你给0


推荐阅读