Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 我希望我的函数返回一个流[T],但我可以';I don’我不知道如何进行型式检验_Scala - Fatal编程技术网

Scala 我希望我的函数返回一个流[T],但我可以';I don’我不知道如何进行型式检验

Scala 我希望我的函数返回一个流[T],但我可以';I don’我不知道如何进行型式检验,scala,Scala,为了更好地学习Scala,我正在做一些基本的编程练习,但我一直在试图弄清楚为什么我的代码不会进行类型检查 关键在于功能。我想要一个函数,它返回一个包含所有可能的数字排列和给定数字列表的数学运算符的流 我很困惑,因为将函数的返回类型更改为readStream[Object]type检查得很好,返回的结果似乎是方程流。但是,下面包含的版本在返回类型possibilites设置为Stream[Equation]时不进行类型检查 作为补充说明,我知道在opsMix中添加卡并不能正确地执行操作,但我想先解

为了更好地学习Scala,我正在做一些基本的编程练习,但我一直在试图弄清楚为什么我的代码不会进行类型检查

关键在于
功能。我想要一个函数,它返回一个包含所有可能的数字排列和给定数字列表的数学运算符的流

我很困惑,因为将函数的返回类型更改为read
Stream[Object]
type检查得很好,返回的结果似乎是方程流。但是,下面包含的版本在返回类型
possibilites
设置为
Stream[Equation]
时不进行类型检查

作为补充说明,我知道在opsMix中添加卡并不能正确地执行
操作,但我想先解决这部分问题。我想我将使用
flatMap
zipAll
flatte
来完成这一部分

还有-这不是家庭作业

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)))
抽象类操作
case类Add()扩展了该操作
case类Subtract()扩展了该操作
case类Multiply()扩展了该操作
case类Divide()扩展了该操作
案例类Num(val-valu:Float)扩展操作
类型方程=列表[操作]
def计算(方程式:方程式):浮动=
马术比赛{
案例编号(x)::列表()=>x
大小写Num(x)::y::Num(z)::xs=>y匹配{
case Add()=>calc(Num(x+z)::xs)
大小写减法()=>calc(Num(x-z)::xs)
case Multiply()=>calc(Num(x*z)::xs)
case Divide()=>calc(Num(x/z)::xs)
}
大小写=>0
}
//从http://stackoverflow.com/questions/1070859/listing-combinations-with-repetitions-in-scala
def mycomb[T](n:Int,l:List[T]):List[List[T]]=
n匹配{
案例0=>List(List())

case \=>for(el问题在于您将操作案例类声明为
Add()
等,但在
val ops
中,您只使用
List(Add…)
。如果您尝试使用正确的类型声明
ops

val ops: List[Operation] = List(Add, Subtract, Multiply, Divide)
您将看到错误。(这就是为什么您自己添加类型而不是依赖类型检查器通常会很有帮助-它有助于查找错误。)

我建议您更新类层次结构,以便对单例操作使用
case-object

  abstract class Operation
  case object Add extends Operation
  case object Subtract extends Operation
  case object Multiply extends Operation
  case object Divide extends Operation
  case class Num(val valu: Float) extends 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
    }
然后,
可能性
按预期工作,没有任何更改

或者,您可以保持类的原有方式,只需将
ops
更改为

val ops: List[Operation] =
    List(Add(), Subtract(), Multiply(), Divide())

更新: 关于交错,您可以执行以下操作:

def interleave[T](xs: List[T], ys: List[T], padX: T, padY: T): List[T] =
  xs.zipAll(ys, padX, padY).flatMap(pair => List(pair._1, pair._2))
def interleave[T](xs: List[T], ys: List[T]): List[T] = {
  import collection.mutable._;
  @annotation.tailrec
  def f(xs: List[T], ys: List[T], r: Buffer[T]): Buffer[T] =
    xs match {
      // By swapping the arguments, we get interelaving:
      case x :: xrest   => f(ys, xrest, r += x);
      case Nil          => r ++= ys;
    }
  return f(xs, ys, new ArrayBuffer[T]).toList;
}
但请注意,结果总是有偶数个元素。也许更好的解决方案是自己实现
交织
,例如:

def interleave[T](xs: List[T], ys: List[T], padX: T, padY: T): List[T] =
  xs.zipAll(ys, padX, padY).flatMap(pair => List(pair._1, pair._2))
def interleave[T](xs: List[T], ys: List[T]): List[T] = {
  import collection.mutable._;
  @annotation.tailrec
  def f(xs: List[T], ys: List[T], r: Buffer[T]): Buffer[T] =
    xs match {
      // By swapping the arguments, we get interelaving:
      case x :: xrest   => f(ys, xrest, r += x);
      case Nil          => r ++= ys;
    }
  return f(xs, ys, new ArrayBuffer[T]).toList;
}
但是,我想说更好的解决方案是不要混合运算和数字。相反,您可以为由符号形成的格式良好的表达式声明一个特殊类,例如(未测试):


而不是创建一个交错列表,而是创建一个
Expression

的实例。问题是您将您的操作用例类声明为
Add()
等,但在
val ops
中,您只使用
list(Add…)
。如果您尝试使用正确的类型声明
ops

val ops: List[Operation] = List(Add, Subtract, Multiply, Divide)
您将看到错误。(这就是为什么您自己添加类型而不是依赖类型检查器通常会很有帮助-它有助于查找错误。)

我建议您更新类层次结构,以便对单例操作使用
case-object

  abstract class Operation
  case object Add extends Operation
  case object Subtract extends Operation
  case object Multiply extends Operation
  case object Divide extends Operation
  case class Num(val valu: Float) extends 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
    }
然后,
可能性
按预期工作,没有任何更改

或者,您可以保持类的原有方式,只需将
ops
更改为

val ops: List[Operation] =
    List(Add(), Subtract(), Multiply(), Divide())

更新: 关于交错,您可以执行以下操作:

def interleave[T](xs: List[T], ys: List[T], padX: T, padY: T): List[T] =
  xs.zipAll(ys, padX, padY).flatMap(pair => List(pair._1, pair._2))
def interleave[T](xs: List[T], ys: List[T]): List[T] = {
  import collection.mutable._;
  @annotation.tailrec
  def f(xs: List[T], ys: List[T], r: Buffer[T]): Buffer[T] =
    xs match {
      // By swapping the arguments, we get interelaving:
      case x :: xrest   => f(ys, xrest, r += x);
      case Nil          => r ++= ys;
    }
  return f(xs, ys, new ArrayBuffer[T]).toList;
}
但请注意,结果总是有偶数个元素。也许更好的解决方案是自己实现
交织
,例如:

def interleave[T](xs: List[T], ys: List[T], padX: T, padY: T): List[T] =
  xs.zipAll(ys, padX, padY).flatMap(pair => List(pair._1, pair._2))
def interleave[T](xs: List[T], ys: List[T]): List[T] = {
  import collection.mutable._;
  @annotation.tailrec
  def f(xs: List[T], ys: List[T], r: Buffer[T]): Buffer[T] =
    xs match {
      // By swapping the arguments, we get interelaving:
      case x :: xrest   => f(ys, xrest, r += x);
      case Nil          => r ++= ys;
    }
  return f(xs, ys, new ArrayBuffer[T]).toList;
}
但是,我想说更好的解决方案是不要混合运算和数字。相反,您可以为由符号形成的格式良好的表达式声明一个特殊类,例如(未测试):


而不是创建一个交错列表,而是创建一个
表达式的实例

谢谢,回答得很好。你的建议完全正确。现在,当我按照计划尝试使用zipAll和flatten时,我遇到了另一个与类型相关的错误…你的第一个想法是如何放置
opMix
交错排列的项目?@DustMason我在答案中添加了一些想法。非常有用,谢谢!您最后的建议更像是“scala方式”对我来说,因为它解决了定义良好的类型化类的问题。谢谢,回答很好。你的建议完全正确。现在,当我按照计划尝试使用zipAll和flatten时,我遇到了另一个与类型相关的错误…你第一个将
s和
opMix
项按交错顺序排列的想法是什么?@DustMason我在答案中添加了一些想法。非常有用,谢谢!您最后的建议对我来说更像是“scala方式”,因为它通过定义良好的类型化类解决了问题。