Coder Social home page Coder Social logo

Add makeInstances? about lens HOT 14 CLOSED

ekmett avatar ekmett commented on June 16, 2024
Add makeInstances?

from lens.

Comments (14)

orenbenkiki avatar orenbenkiki commented on June 16, 2024

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.

ekmett avatar ekmett commented on June 16, 2024

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.

orenbenkiki avatar orenbenkiki commented on June 16, 2024

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.

ekmett avatar ekmett commented on June 16, 2024

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.

orenbenkiki avatar orenbenkiki commented on June 16, 2024

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.

ekmett avatar ekmett commented on June 16, 2024

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.

orenbenkiki avatar orenbenkiki commented on June 16, 2024

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.

ekmett avatar ekmett commented on June 16, 2024

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.

orenbenkiki avatar orenbenkiki commented on June 16, 2024

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.

ekmett avatar ekmett commented on June 16, 2024

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.

orenbenkiki avatar orenbenkiki commented on June 16, 2024

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.

ekmett avatar ekmett commented on June 16, 2024

It gets even more annoying when there are multiple constructors. ;)

from lens.

orenbenkiki avatar orenbenkiki commented on June 16, 2024

Yikes, I never even considered that. That would get very hairy indeed, especially with makeClassy...

from lens.

ekmett avatar ekmett commented on June 16, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.