2015-03-01 19 views
6

Có cách nào để tạo chuỗi trong FsCheck hay không bằng cách chỉ chọn một mục từ mỗi danh sách chuỗi và sau đó ghép nối kết quả?Máy phát điện FsCheck bằng cách chọn từ các hồ chứa khả năng

Tôi hoàn toàn bị kẹt và dường như không thể tìm ra. Tôi đã xem số docs và trong số github repo cho nội dung tương tự. Và tôi đã thực hiện hầu hết việc đọc trên FsCheck từ FSharpForFunAndProfit.

Đây là một cái gì đó giống như những gì tôi sẽ nghĩ đến việc:

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ê"] 

Điều đó sẽ tạo ra một cái gì đó như "Z0ê" hoặc "Zoe".

+0

Viết hàm bạn muốn mà tạo ra một 'chuỗi seq' sau đó áp dụng' Gen.elements'. –

Trả lời

6

Điều này có làm những gì bạn muốn không?

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 

thử nghiệm Ad-hoc:

open FsCheck.Xunit 

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

Output (cắt ngắn):

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

Giải thích

Chức năng createGenerators có loại seq string -> Gen<char> list, và nó tạo ra một Gen từ mỗi chuỗi sử dụng Gen.elements, bởi vì một chuỗi cũng là char seq; Gen.elements tạo một Gen sẽ chọn một trong các giá trị char này từ mỗi chuỗi.

Sau đó, sử dụng Gen.sequence để chuyển đổi Gen<char> list thành Gen <char list> và sau đó ánh xạ từ đó.


BTW, bạn cũng có thể nội tuyến createGenerators:

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

Cảm ơn Mark! Có vẻ như nó sẽ hoạt động. – Sobieck

+0

+1 Câu trả lời tuyệt vời và cũng được tạo thủ công (như được hiển thị từ [chỉnh sửa của nó] (http://stackoverflow.com/posts/28798955/revisions))! - Làm thế nào về việc sử dụng 'List.reduce (+)' thay vì 'String.concat" "'? –

+2

Vấn đề với 'List.reduce' là nó dễ vỡ, vì vậy tôi có xu hướng tránh nó. Hãy thử điều này nếu bạn không tin tôi: 'List.empty |> List.reduce (+)'. –

Các vấn đề liên quan