Scala をよりよく学習するために、いくつかの基本的なプログラミング演習を行っていますが、コードが型チェックを行わない理由を突き止めようとしています。
こだわりポイントはpossibilities
機能です。数値のリストを指定して、数値と数学演算子のすべての可能な配置を含むストリームを返す関数が必要です。
Stream[Object]
関数の戻り値の型を型チェックを読み取るように変更すると、問題なく方程式のストリームのように見える結果が返されるため、私は混乱しています。ただし、以下に含まれるバージョンは、戻り値の型が に設定されている型チェックを行いません。possibilites
Stream[Equation]
補足として、カードに opsMix を追加するとOperation
s が正しい順序にならないことは理解していますが、最初に問題のこの部分を解決したいと思います。その部分を達成するためにflatMap
or zipAll
withを使用すると思います。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)))