Я пытаюсь написать экземпляр Monad Transformer для типа Gen
ScalaCheck.
То есть: такой тип, как следующий, который может использоваться в качестве монады, при условии, что нижележащий функтор F
- это Монада.
case class GeneratorT[F[_], A](generator: Gen[F[A]])
object GeneratorT {
implicit def monadForGeneratorT[F[_]: Monad]: Monad[GeneratorT[F, *]] = new Monad[GeneratorT[F, *]] {
...
}
}
При написании этого я понял, что было бы полезно, если бы я смог написать экземпляр Distributive
для Gen
, потому что тогда я мог бы написать flatMap
для GeneratorT
следующим (несколько запутанным) образом:
override def flatMap[A, B](ga: GeneratorT[F, A])(fun: A => GeneratorT[F, B]): GeneratorT[F, B] = {
GeneratorT[F, B](ga.generator.flatMap(fa => fa.map(a => fun(a).generator).distribute(identity).map(_.flatten)))
}
Инстинктивно я чувствую, что могу написать Distributive
экземпляр для Gen
, потому что Gen
- это больше или less просто функция из некоторой конфигурации и начальное значение для значения, а функции являются дистрибутивными.
С учетом вышесказанного мне не удалось найти пример того, как кто-то делает это, и я изо всех сил пытаюсь написать это, потому что ScalaCheck не раскрывает внутренности Gen
.
Возможно ли это?