purescript-prelude
purescript-prelude copied to clipboard
[generics-rep] Document the associativity of Product and Sum that the compiler generates
With instance chains you can distinguish between Product a (Product b c)
and Product (Product a b) c
. It would be helpful to note the ambiguity and what the compiler generates in practice.
Did some research; we could add something along the lines of this to the docs:
At the moment, the compiler brackets Sums and Products right-associatively. For example:
> data TestSum = TestA | TestB | TestC | TestD
> derive instance genericTestSum :: G.Generic TestSum _
> :t (G.to :: _ -> TestSum)
Sum (Constructor "TestA" NoArguments) (Sum (Constructor "TestB" NoArguments) (Sum (Constructor "TestC" NoArguments) (Constructor "TestD" NoArguments))) -> Test
> data TestProduct = TestProduct Int Int Int Int
> derive instance genericTestProduct :: G.Generic TestProduct _
> :t (G.to :: _ -> TestProduct)
Constructor "TestProduct" (Product (Argument Int) (Product (Argument Int) (Product (Argument Int) (Argument Int)))) -> TestProduct
Ideally, the compiler would bracket up Sums and Products so as to minimize the depth of the resulting tree; this would help generate faster code when constructing or pattern-matching on generic representation types. This nesting may change in a future release, so it is recommended to avoid depending on the way the compiler chooses to nest Sums and Products if at all possible.