gpt4 book ai didi

f# - 为递归记录制作 FsCheck 生成器

转载 作者:行者123 更新时间:2023-12-01 04:57:00 25 4
gpt4 key购买 nike

我有这样的递归类型:

type QueryInfo =
{ Title : string
Check : Client -> bool
Positive : Decision
Negative : Decision }

and Decision =
| Result of string
| Query of QueryInfo

我要为 FsCheck 制作一个发电机.我看过this我对 static member 这样的方法不感兴趣。我的主要问题是每个字段都有不同的类型。

FsCheck 已经可以生成 QueryInfo 的值,但是由于该类型是递归的,生成的值可以嵌套得如此之深,以至于值的生成实际上永远不会停止(或者,至少)非常慢。

最佳答案

像这样的东西应该可以工作:

let qi =
let createQi t c p n = {
Title = t
Check = c
Positive = p
Negative = n }
let makeQiGen =
Gen.map4 createQi Arb.generate<string> Arb.generate<Client -> bool>
let resultGen = Arb.generate<string> |> Gen.map Result
let rec qi' size =
if size <= 0
then makeQiGen resultGen resultGen
else
let subQi = qi' (size - 1) |> Gen.map Query
Gen.oneof [
makeQiGen resultGen resultGen
makeQiGen subQi subQi
makeQiGen resultGen subQi
makeQiGen subQi resultGen ]
Gen.sized qi'

本质是防止无限(或非常深)的递归,这是由Gen.sized完成的。

size 达到 0 时,生成器总是返回一个叶节点 - 即:PositiveNegativeResult 值。

size 大于 0 时,生成器从四个生成器中选择一个:

  • 生成叶子的
  • 一个生成新节点的节点,其中 PositiveNegative 都是新的 Query 值。
  • Positive 是一个Result,而Negative 是一个Query
  • 其中 Positive 是一个 Query,而 Negative 是一个 Result

不过,在每次递归中,size 都会递减,因此最终会返回一个叶节点。

此答案基于 the FsCheck documentation生成递归数据类型部分.

关于f# - 为递归记录制作 FsCheck 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33880972/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com