我正在玩一些基本的编程练习,以更好地学习Scala,但我坚持试图找出为什么我的代码不会输入check。我想我的函数返回一个流[T],但我不知道如何使它类型检查
该问题的关键是possibilities
函数。我想要一个函数返回一个包含数字和数学运算符的所有可能排列的数据流。
我很困惑,因为改变函数的返回类型来读取Stream[Object]
类型检查就好了,并返回看起来是等式流的结果。但是,包含在以下的版本不会类型检查,返回类型possibilites
设置为Stream[Equation]
。
作为一个方面说明,我知道用卡添加opsMix并不会将Operation
按正确顺序排列,但我想先解决这部分问题。我想我会用flatMap
或zipAll
与flatten
来完成那部分。
另外 - 这不是一项家庭作业!
abstract class Operation
case class Add() extends Operation
case class Subtract() extends Operation
case class Multiply() extends Operation
case class Divide() extends Operation
case class Num(val valu: Float) extends Operation
type Equation = List[Operation]
def calc(equa: Equation): Float =
equa match {
case Num(x) :: List() => x
case Num(x) :: y :: Num(z) :: xs => y match {
case Add() => calc(Num(x + z)::xs)
case Subtract() => calc(Num(x - z)::xs)
case Multiply() => calc(Num(x * z)::xs)
case Divide() => calc(Num(x/z)::xs)
}
case _ => 0
}
// from http://stackoverflow.com/questions/1070859/listing-combinations-with-repetitions-in-scala
def mycomb[T](n: Int, l: List[T]): List[List[T]] =
n match {
case 0 => List(List())
case _ => for(el <- l;
sl <- mycomb(n-1, l dropWhile { _ != el }))
yield el :: sl
}
def comb[T](n: Int, l: List[T]): List[List[T]] = mycomb(n, l.removeDuplicates)
val ops = List(Add, Subtract, Multiply, Divide)
def possibilities(cards: List[Num]) : Stream[Equation] =
{ for {
hand <- cards.permutations
opMix <- comb(cards.length-1, ops)
} yield hand ++ opMix
}.toStream
// test value:
val ppp = possibilities(List(Num(20), Num(3), Num(7), Num(100)))
谢谢,很好的答案。你的建议是完全正确的。现在,当按照我的计划尝试使用zipAll和flatten时,我遇到了另一个类型相关的错误......将“card”和“opMix”项以交错顺序排列的第一个想法是什么? – 2013-02-17 21:37:21
@DustMason我给答案增加了一些想法。 – 2013-02-17 22:57:44
非常有帮助,谢谢!您的最终建议对我来说更像是“scala方式”,因为它可以通过定义明确的类型类来解决问题。 – 2013-02-18 01:00:38