我对ScalaCheck (和Scala完全)还很陌生,所以这可能是一个相当简单的解决方案。
我使用ScalaCheck为AST生成测试,并验证写入器/解析器是否工作。我有这些文件
AST.scala
package com.test
object Operator extends Enumeration {
val Add, Subtract, Multiply, Divide = Value
}
sealed trait AST
case class Operation(left: AST, op: Operator.Value, right: AST) extends AST
case class Literal(value: Int) extends ASTGenOperation.scala
import com.test.{AST, Literal}
import org.scalacheck._
import Shrink._
import Prop._
import Arbitrary.arbitrary
object GenLiteral extends Properties("AST::Literal") {
property("Verify parse/write") = forAll(genLiteral){ (node) =>
// val string_version = node.writeToString() // AST -> String
// val result = Parse(string_version) // String -> AST
true
}
def genLiteral: Gen[Literal] = for {
value <- arbitrary[Int]
} yield Literal(value)
implicit def shrinkLiteral: Shrink[AST] = Shrink {
case Literal(value) =>
for {
reduced <- shrink(value)
} yield Literal(reduced)
}
}GenOperation.scala
import com.test.{AST, Operation}
import org.scalacheck._
import Gen._
import Shrink._
import Prop._
import GenLiteral._
object GenOperation extends Properties("AST::Operation") {
property("Verify parse/write") = forAll(genOperation){ (node) =>
// val string_version = node.writeToString() // AST -> String
// val result = Parse(string_version) // String -> AST
true
}
def genOperation: Gen[Operation] = for {
left <- oneOf(genOperation, genLiteral)
right <- oneOf(genOperation, genLiteral)
op <- oneOf(Operator.values.toSeq)
} yield Operation(left,op,right)
implicit def shrinkOperation: Shrink[AST] = Shrink {
case Operation(l,o,r) =>
(
for {
ls <- shrink(l)
rs <- shrink(r)
} yield Operation(ls, o, rs)
) append (
for {
ls <- shrink(l)
} yield Operation(ls, o, r)
) append (
for {
rs <- shrink(r)
} yield Operation(l, o, rs)
) append shrink(l) append shrink(r)
}
}在我编写的示例代码(上面粘贴的代码)中,我得到了错误
ambiguous implicit values:
both method shrinkLiteral in object GenLiteral of type => org.scalacheck.Shrink[com.test.AST]
and method shrinkOperation in object GenOperation of type => org.scalacheck.Shrink[com.test.AST]
match expected type org.scalacheck.Shrink[com.test.AST]
ls <- shrink(l)我如何为这个编写收缩方法?
发布于 2017-04-03 13:51:39
您有两个隐式Shrink[AST]实例,因此编译器抱怨含糊不清的隐式值。
您可以将代码重写为:
implicit def shrinkLiteral: Shrink[Literal] = Shrink {
case Literal(value) => shrink(value).map(Literal)
}
implicit def shrinkOperation: Shrink[Operation] = Shrink {
case Operation(l,o,r) =>
shrink(l).map(Operation(_, o, r)) append
shrink(r).map(Operation(l, o, _)) append ???
}
implicit def shrinkAST: Shrink[AST] = Shrink {
case o: Operation => shrink(o)
case l: Literal => shrink(l)
}https://stackoverflow.com/questions/42581883
复制相似问题