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