Ответ 1
Это неплохая идея - на самом деле все дело в том, что вы в состоянии это сделать. Генераторы FsCheck полностью композиционны.
Обратите внимание, что если у вас есть неизменные объекты, конструкторы которых принимают примитивные типы, например, ваш напиток и тарелка, FsCheck может генерировать их из коробки (используя отражение)
let drinkArb = Arb.from<Drink>
let dishArb = Arb.from<Dish>
должен предоставить вам произвольный экземпляр, который является генератором (генерирует случайный экземпляр Drink) и сжимает (принимает экземпляр Drink и делает его "меньше" - это помогает при отладке, особенно для составных структур, где вы получаете небольшой встречный пример, если ваш тест не прошел).
Это довольно быстро ломается - в вашем примере вы, вероятно, не хотите отрицательных целых чисел для количества напитков или количества блюд. Приведенный выше код будет генерировать отрицательные числа. Иногда это легко исправить, если ваш тип действительно просто оболочка какого-то типа вокруг другого типа, используя Arb.convert, например.
let drinksArb = Arb.Default.PositiveInt() |> Arb.convert (fun positive -> new Drinks(positive) (fun drinks -> drinks.Amount)
Вам нужно предоставить и от конверсий к Arb.convert и presto, новый произвольный экземпляр для Drinks, который поддерживает ваш инвариант. Другие инварианты, возможно, не так легко поддерживать, конечно.
После этого становится немного сложнее генерировать генератор и сушку одновременно с этими двумя частями. Всегда начинайте с генератора, а затем сжимается, если (когда) вам это нужно. Пример @simonhdickson выглядит разумно. Если у вас есть произвольные экземпляры выше, вы можете получить их генератор, вызвав .Generator.
let drinksGen = drinksArb.Generator
Как только у вас есть генераторы деталей (Drink and Dish), вы можете составить их вместе, поскольку @simonhdickson предлагает:
let menuGenerator =
Gen.map3 (fun a b c -> Menu(a,b,c)) (Gen.listOf dishGenerator) (Gen.listOf drinkGenerator) (Arb.generate<int>)
Разделите и победите! В целом взгляните на то, что intellisense от Gen дает вам представление о том, как создавать генераторы.