加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scalacheck收缩

发布时间:2020-12-16 18:50:21 所属栏目:安全 来源:网络整理
导读:我对 ScalaCheck(和 Scala完全)相当新,所以这可能是一个相当简单的解决方案 我正在使用ScalaCheck为AST生成测试并验证编写器/解析器是否正常工作.我有这些文件 AST.scala package com.testobject Operator extends Enumeration { val Add,Subtract,Multiply,
我对 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 AST

GenOperation.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,rs)
        ) append (
        for {
          ls <- shrink(l)
        } yield Operation(ls,r)
        ) append (
        for {
          rs <- shrink(r)
        } yield Operation(l,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)

如何为此编写收缩方法?

解决方法

你有两个隐式的Shrink [AST]实例,所以编译器抱怨含糊不清的隐含值.

您可以将代码重写为:

implicit def shrinkLiteral: Shrink[Literal] = Shrink {
  case Literal(value) => shrink(value).map(Literal)
}

implicit def shrinkOperation: Shrink[Operation] = Shrink {
  case Operation(l,r) =>
    shrink(l).map(Operation(_,r)) append
    shrink(r).map(Operation(l,_)) append ???
}

implicit def shrinkAST: Shrink[AST] = Shrink {
  case o: Operation => shrink(o)
  case l: Literal => shrink(l)
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读