-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Arg type prisms #642
base: master
Are you sure you want to change the base?
Arg type prisms #642
Conversation
… they can be utilized in Control.Lens.Internal.PrismTH
…nstead of a tuple. E.g. prs = --some suitable definition data A = A1 {_a :: Int, _b :: Int } | A2 {_c :: Int, _d :: Int} makeArgTypePrisms prs ''A Will generate: data A1Args = A1Args Int Int data A2Args = A2Args Int Int _A1 :: Prism' A A1Args a :: Lens' A1Args Int b :: Lens' A1Args Int _A2 :: Prism' A A2Args c :: Lens' A2Args Int d :: Lens' A2Args Int Add functions makeArgTypePrisms makeArgTypeDecPrisms and type PrismRulesSelector to interface of Control.Lens.Internal.PrismTH. These functions take an additional parameter of type PrismRulesSelector (= Name -> Maybe (Name, LensRules)). This function is applied to each constructor name. A Nothing causes the existing tuple behaviour to trigger, and a Just (n, rules) causes a data type and its lenses to be generated. This required changes to much of PrismTH, threading the PrismRulesSelector through, then using it to compute a PrismTarget which is stored in the Stab. This commit passes tests on GHC 7.10.3. So tuple prisms should still be working, but I don't expect ArgType prisms to be working yet.
…Fields which was moved previously.
…o exports of Control.Lens.TH. Add argTypesRulesSelector :: PrismRulesSelector. This function appends Args to the name of the constructor and passes defaultFieldRules. Add some tests to templates.hs to exercise the new prism code. These tests currently fail.
This might be a bit dodgy, needs a review.
uses lensRules, except names the lens by prepending an underscore to the field name.
Rename PrismTargetNewtype to PrismTargetDataType Add a field of type [TyVarBndr] to PrismTargetDataType. This is required so that we can remember the order of type variables. Add HasTypeVars and SubstType instances for PrismTarget Fix targetType for the PrismTargetDataType case Fix targetDecs Fix computePrismStab and computeIsoType Add tests for the Prism ArgTypes feature
Fix some lints Attempt to fix failure to compile on ghc-8 caused by change to template-haskell, don't have this compiler so I haven't tested this.
I confess to being a bit conflicted about this. |
I did this work when I was working with the ghc api, and it's plethora of data types with many constructors of many arguments. In general I don't find the existing prisms particularly useful for constuctors with more than 2 or 3 arguments, and these arg type prisms were useful then. I wasn't able to find a way to build this without copying a lot of the internal lens code Feel free to close if you're not interested, or I'm happy to take direction on helping to turn this into something acceptable. |
Hi,
This PR expands the capability of prism-generating template haskell. Constructors that take multiple arguments have data types for those arguments generated, and the prisms for those constructors target the generated data types instead of tuples. The generated data types also have lenses generated.
Two new functions, declareArgTypePrisms and makeArgTypePrisms, are added that take a Parameter of type
Name -> Maybe (Name, LensRules)
. This function is applied to each constructor name. A result of Nothing will cause tuple prisms to be generated as usual, while a result of Just (n, lr) will cause a data type n to be generated, and lenses on that data type to be generated using lr.e.g.
Will generate:
I have added some tests to templates.hs to exercise the new functionality.
I'm not confident that the names of chosen are any good.
Please let me know if you are interested in merging this.