Comments (14)
Yes, this is a separate issue and using makeInstances
is a better approach. I assume reify
would be kind enough to provide a list of instances for the field types for locating the "HasType" ones... and, of course, having makeInstancesFor
for explicit decision of which fields to/not create instances for would be needed.
from lens.
One issue with this is it means that the ordering in the source file becomes rather significant as to which instances get silently created. I'm not sure how I feel about that.
from lens.
I don't see instances getting "silently created", makeInstances
seems pretty explicit, right? And the programmer has some freedom about where he puts code relative to makeInstances
(or makeLenses
for that matter). At any rate, this is inherent to Template Haskell and nothing to do with lenses as of themselves...
This is something I never "got" about Template Haskell. On the one hand, it imposes an order between "before the splice point" and "after the splice point". At the same time, it is impossible to use inside $( )
anything that appears "before the splice point" in the same module. It isn't clear why we have both constraints. If compilation is done piecemeal, one would expect to be able to refer to the already-compiled code "before the splice point". If compilation is done in one pass, one would expect order not to matter at all. I suppose the story is far more complex, which is why we end up with the worse of both worlds. Sigh. Sometimes Template Haskell makes me wonder whether I should have picked Clojure instead of Haskell for my system ;-)
from lens.
I think with the separate makeInstances
call it would be explicit enough.
The trick is actually writing the thing, because it needs the template haskell generation code to do unification and for us to probably solve #49 as an intermediate step.
from lens.
I agree that #49 needs to be done first, but why do we need unification? It isn't clear to me how one gets the list of instances for a type (but you implied there was a way). Other than that, it is a simple matter of emitting "instance of HasFoo Bar where foo = theLensOfBarWithTheFooValue", right...?
from lens.
The problem is when Bar a b
has a field with a type like Foo a
, then I need to find HasFoo
, figure out the MPTC parameters unify a
's and derive
instance HasFoo (Bar a b) a where
foo = barFoo
I'm not inclined to derive a one-off hack for the unparameterized form if we're just going to have to throw it all away the moment we address #49.
from lens.
You are right, this would need to be done, and that's another reason why #49 should be done first. That said, the original definition of Bar a b
would have an explicit mapping from a b
to whatever type parameters Foo
takes, as part of the barFoo
field, so "all" you'd need to do is apply the same mapping when setting up the instance... admittedly doing all this in TH is a PITA. Maybe reusing exactly the same type variable names may allow some reuse of the AST, but I wouldn't bet on it.
from lens.
We already do something like this when generating the types of lenses in the first place. We figure out what types from the container are referenced in the target fields, then freshen the remainder to get things like
data Foo a b c d = Foo { _foo :: a, _bar :: b, _baz :: (b,c) }
makeLenses ''Foo
foo :: Lens (Foo a b c d) (Foo e b c f) a e
bar :: Lens (Foo a b c d) (Foo a b c e) b b
baz :: Lens (Foo a b c d) (Foo a b e f) (b,c) (b,e)
A large part of the alchemy is taken care of the alpha substitution traversals I put in Control.Lens.TH.Traversal
.
This is actually an easier problem than a bigger outstanding problem we have which is to do unification properly for unifying field types for traversals. (Right now we assume the types all match the type of the first field traversed).
from lens.
If foo
is an a e
, shouldn't bar
be a b e
and baz
be (e f)
(with the appropriate additional modifications for consistency, of course)?
from lens.
I wasn't quite able to parse that.
To explain what I meant:
All of them let d
vary, because they don't use it.
foo
's target is completely unconstrained.
bar
's b
is also used by baz
so a local edit to bar
, one that ignores baz
, can't change the type of that field.
otoh, baz
is only partially constrained by the existence of bar
, so its not allowed to change its fst
(b
) type, but the type of the second part of the pair is still up for grabs.
from lens.
Oh, I see, it is due to being bound by the existence of other fields. Quite right, and makes me even more appreciative of the the fact you didn't take the easy way out by just keeping the types the same, and the complexities of getting all this package right...
from lens.
It gets even more annoying when there are multiple constructors. ;)
from lens.
Yikes, I never even considered that. That would get very hairy indeed, especially with makeClassy
...
from lens.
This issue has been dead in the water for a long time.
I'm closing this out as a 'wontfix' issue, mostly because it isn't clear that it can be done, and there are the host of problems with this approach raised above.
from lens.
Related Issues (20)
- Are state modifications supposed to be so lazy? HOT 1
- Dead link in description HOT 1
- No accessors are generated when using `NoFieldSelectors` to remove prefixes. HOT 3
- Splitting Ixed/At/Contains into their own package HOT 2
- Build failure with GHC-9.6, mtl-2.3.1 but transformers-0.5 HOT 12
- Negative Index onto Text type results in returning first element HOT 4
- Add `toAlternativeOf`? HOT 7
- Declare Fields with Nested Records of types defined in same Splice HOT 1
- Replace the creately diagram
- HLint fails in master HOT 2
- cloneGetter HOT 2
- Improving documentation HOT 11
- Deprecate 'lifted'? HOT 1
- Build failure with `template-haskell-2.21` (GHC 9.8) HOT 2
- trying to understand some accesssor stuff HOT 2
- Censor & listen
- Separate Each into own package HOT 3
- Order dependence for `makeFields` HOT 10
- Improve `rewriteM` docs
- Skillsmatter video is not online anymore? HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lens.