【问题标题】:Type mismatch in for comprehension: getting "Product with Serializable"输入不匹配以进行理解:获取“具有可序列化的产品”
【发布时间】:2017-03-02 16:33:21
【问题描述】:

我正在编写一个函数,它将获取字符串中出现的字符 (List[(Char, Int)]) 的列表,并生成该出现列表的所有子集。

所以,给定

List(('a', 2), ('b', 2))

它会产生

List(
  List(),
  List(('a', 1)),
  List(('a', 2)),
  List(('b', 1)),
  List(('a', 1), ('b', 1)),
  List(('a', 2), ('b', 1)),
  List(('b', 2)),
  List(('a', 1), ('b', 2)),
  List(('a', 2), ('b', 2))
)

我是这样实现的:

type Occurrences = List[(Char, Int)]

def combinations(occurrences: Occurrences): List[Occurrences] =
  if (occurrences.isEmpty) List(List())
  else for {
    (c, n) <- occurrences
    i <- n to 1 by -1
  } yield (c, i) :: combinations(occurrences.tail)

我得到这个错误:

type mismatch;
 found   : List[List[Product with Serializable]]
 required: List[Occurrences]
    (which expands to)  List[List[(Char, Int)]]

请帮助我理解,为什么会发生这种情况,我该如何解决?

我尝试将其重写为 flatMap...,使用 Intellij 的“解释 Scala 代码”等。

【问题讨论】:

  • 有什么特殊原因阻止您接受答案?

标签: scala types yield for-comprehension


【解决方案1】:

其实是少了括号:

type Occurrences = List[(Char, Int)]

  def combinations(occurrences: Occurrences): List[Occurrences] =
    if (occurrences.isEmpty) List(List())
    else (for {
      (c, n) <- occurrences
      i <- n to 1 by -1
    } yield (c, i)) :: combinations(occurrences.tail)

在您用于理解的原始代码中,试图生成 (c, i) :: combinations(occurrences.tail),即 List,其中包含 Any 元素(Tuple/另一个 List)。

更新:

需要魔法的正确方法:

type Occurrences = List[(Char, Int)]


  /**
    * Returns the list of all subsets of the occurrence list.
    *  This includes the occurrence itself, i.e. `List(('k', 1), ('o', 1))`
    *  is a subset of `List(('k', 1), ('o', 1))`.
    *  It also include the empty subset `List()`.
    *
    *  Example: the subsets of the occurrence list `List(('a', 2), ('b', 2))` are:
    *
    *    List(
    *      List(),
    *      List(('a', 1)),
    *      List(('a', 2)),
    *      List(('b', 1)),
    *      List(('a', 1), ('b', 1)),
    *      List(('a', 2), ('b', 1)),
    *      List(('b', 2)),
    *      List(('a', 1), ('b', 2)),
    *      List(('a', 2), ('b', 2))
    *    )
    *
    *  Note that the order of the occurrence list subsets does not matter -- the subsets
    *  in the example above could have been displayed in some other order.
    */
  def combinations(occurrences: Occurrences): List[Occurrences] =
    occurrences.foldRight(List[Occurrences](Nil)) {
      case ((ltr, cnt), acc) =>
        acc ::: (for {
          comb <- acc
          ltrNum <- 1 to cnt
        } yield (ltr, ltrNum) :: comb)
    }

感谢this code的作者。

【讨论】:

  • 括号解决了类型,但改变了代码的预期行为。我试图准确地产生(c, i) :: combinations(occurrences.tail)
  • 让我们分解一下:combinations(occurrences.tail) 的类型为 List[List[(Char, Int)]]。您尝试附加(c, i),即(Char, Int)。你应该附加List[(Char, Int)]
  • 但是即使在那之后它也没有产生所需的结果,这让我认为算法本身并不完全正确。我不打算发布算法问题的解决方案,因为您的问题要求解决编译问题。
  • 请查看更新,它包含满足您需要的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 2019-12-26
  • 1970-01-01
  • 2012-08-30
相关资源
最近更新 更多