【问题标题】:FsCheck Generators by Selecting From Pools of Possibilities从可能性池中选择 FsCheck 生成器
【发布时间】:2015-03-02 22:21:40
【问题描述】:

有没有办法在 FsCheck 中生成一个字符串,方法是从每个字符串列表中选择一个项目,然后连接结果?

我完全陷入困境,似乎无法弄清楚。我查看了docsgithub 回购中的类似内容。我已经阅读了大部分来自FSharpForFunAndProfit 的 FsCheck。

这和我想的差不多:

let rand = System.Random()
let randInt max = rand.Next(0, max)

let selectLetter (string: string) = 
    let whichLettersIndex = String.length string |> randInt
    string.Substring(whichLettersIndex, 1)

let generateOddlySpelledWord listOfStrings = 
    List.map selectLetter listOfStrings
    |> String.concat ""

let usingGenerateOddlySpelledWord =
    generateOddlySpelledWord ["zZ"; "oO0Ò"; "eEê"]

这应该会生成类似“Z0ê”或“zÒE”的东西。

【问题讨论】:

  • 编写你想要生成string seq的函数,然后应用Gen.elements

标签: f# fscheck


【解决方案1】:

这是你想要的吗?

open FsCheck

let createGenerators (l : string seq) =
    l |> Seq.map Gen.elements |> Seq.toList

type OddlySpelledWords =
    static member String() =
        ["zZ"; "oO0Ò"; "eEê"]
        |> createGenerators
        |> Gen.sequence
        |> Gen.map (List.map string >> String.concat "")
        |> Arb.fromGen

临时测试:

open FsCheck.Xunit

[<Property(Arbitrary = [| typeof<OddlySpelledWords> |])>]
let test (s : string) =
    printfn "%s" s

输出(截断):

  z0ê
  ZÒe
  ZOe
  zoê
  ZÒe
  zoê
  Z0e
  zoê
  z0ê
  ZOe
  zÒê
  z0E
  zoe

说明

createGenerators 函数的类型为seq string -&gt; Gen&lt;char&gt; list,它使用Gen.elements 从每个字符串创建一个Gen,因为字符串也是char seqGen.elements 创建一个 Gen,它将从每个字符串中选择其中一个 char 值。

然后它使用Gen.sequenceGen&lt;char&gt; list 转换为Gen &lt;char list&gt;,然后从那里映射。


顺便说一句,你也可以内联createGenerators

type OddlySpelledWords =
    static member String() =
        ["zZ"; "oO0Ò"; "eEê"]
        |> List.map Gen.elements
        |> Gen.sequence
        |> Gen.map (List.map string >> String.concat "")
        |> Arb.fromGen

【讨论】:

  • +1 很好的答案,而且制作精良(如its edits 所示)! – 用List.reduce (+)代替String.concat ""怎么样?
  • List.reduce 的问题是它很脆弱,所以我倾向于避免它。如果你不相信我,试试这个:List.empty&lt;string&gt; |&gt; List.reduce (+).
  • +1 实际上,出于好奇,List.empty&lt;string&gt; |&gt; List.reduce (+) 抛出了一个 ArgumentException,表示输入列表为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-05
  • 2016-07-19
  • 2016-07-21
  • 2012-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多