2015-01-20 1 views
1
module BirthdayLibrary = 
    type Birthday = 
     { day :int 
      month :int } 

module DataGen = 
    let birthdayGenerator (months:option<list<int>>) = 
     let monthGen = match months with 
         | Some m -> Gen.elements m 
         | None -> FsCheck.Gen.choose(1,12) 
     (fun m d -> { day = d 
         month = m}:BirthdayLibrary.Birthday) 
     <!> monthGen 
     <*> FsCheck.Gen.choose(1,28) 

    //I want this to have the signature Gen<BirthdayLibrary.Birthday list> 
    let oneForEveryMonthGen = 
     [ for m in [1 .. 12] -> 
      (fun mo -> birthdayGenerator (Some [mo]))] 

Допустим, у меня что-то вроде выше. У меня есть генератор рождения с возвратом типа Gen <BirthdayLibrary.Birthday>. Вы можете указать месяц. Каков наилучший способ перехода от генератора <a> к генератору < a список > WHILE, определяющее некоторое ограничение на элемент в гене списка? Я могу думать о способах получить < Gen <a> >, который, как я думаю, не будет работать для составления родительского объекта, который должен содержать список <a> (который является основой для этого примера). Я также могу придумать способ сделать Gen < Gen <a> >, в котором у меня были проблемы с композицией, а также все значения в списке были одинаковыми. Я видел бит Gen.arrayOf, я не могу придумать, как заставить его работать со значениями для каждого элемента массива.Есть ли способ перейти от Gen <a> к Gen <a list> с указанием ссылки?

+0

Я добавлю ответ, который даст вам подпись, которую вы хотите, а также ограничение, но я должен признаться, что не совсем понимаю, с чем вы сталкиваетесь проблемы с композицией. –

+0

По проблемам состава я имел в виду, что я не смог развернуть список Gen > для использования с объектом, имеющим свойство типа . – Hohohodown

ответ

2
module BirthdayLibrary = 
    type Birthday = 
     { day :int 
      month :int } 

module DataGen = 
    let birthdayGenerator (months:option<list<int>>) = 
     let monthGen = match months with 
         | Some m -> Gen.elements m 
         | None -> FsCheck.Gen.choose(1,12) 
     (fun m d -> { day = d 
         month = m}:BirthdayLibrary.Birthday) 
     <!> monthGen 
     <*> FsCheck.Gen.choose(1,28) 

    //I want this to have the signature Gen<BirthdayLibrary.Birthday list> 
    let oneForEveryMonthGen = 
     [ for m in [1 .. 12] -> birthdayGenerator (Some [m])] 
     |> Gen.sequence 

let sample = DataGen.oneForEveryMonthGen |> Gen.sample 10 1 

дает мне:

вал выборки: список список BirthdayLibrary.Birthday = [[{день = 7; month = 1;}; {день = 15; month = 2;}; {день = 13; month = 3;}; {день = 14; month = 4;}; {день = 28; month = 5;}; {день = 9; month = 6;}; {день = 28; month = 7;}; {день = 15; month = 8;}; {день = 6; month = 9;}; {день = 21; month = 10;}; {день = 12; month = 11;}; {день = 27; month = 12;}]]