purescript-prelude icon indicating copy to clipboard operation
purescript-prelude copied to clipboard

[generics-rep] Document the associativity of Product and Sum that the compiler generates

Open natefaubion opened this issue 6 years ago • 1 comments

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.

natefaubion avatar Jul 30 '18 21:07 natefaubion

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.

hdgarrood avatar Jul 18 '20 13:07 hdgarrood