kcsongor / generic-lens

Generically derive traversals, lenses, and prisms.
437 stars 53 forks source link

Allow users to somehow reference non-exported constraints #79

Closed LightAndLight closed 5 years ago

LightAndLight commented 5 years ago

There are some programs that I can't give a type signature, because the constraints I need to add to the signature are not exported by generic-lens. For example, with Data.Generics.Product.Typed:

theInt :: (Generic s, HasType Int s) => Lens' s Int
theInt = typed @Int

I can't finish this definition, because I can't reference ErrorUnlessOne and HasTotalTypePSym.

I think that just exporting these names would be unwieldy, so we could define a constraint synonym for them:

type HasTypeConstraints a s =
  ( ErrorUnlessOne a s (CollectTotalType a (Rep s))
  , GLens (HasTotalTypePSym a) (Rep s) (Rep s) a a
  )

 instance
  ( Generic s
  , HasTypeConstraints a s
  ) => HasType a s where
...

Then HasTypeConstraints can be exported along with HasType.

Now my definition becomes:

theInt :: (Generic s, HasTypeConstraints Int s, HasType Int s) => Lens' s Int
theInt = typed @Int

Which should now compile.


What do you think? A similar approach would follow for all the classes. I'm happy to do the work if you think this is useful.

Lysxia commented 5 years ago

It seems you swapped HasType Int s in the signature of theInt. And that would indeed be equivalent to HasTypeConstraints s Int. That said it might be worth adding a comment to HasType because these parameters are easy to mix up.

LightAndLight commented 5 years ago

Thanks, I've fixed it to be consistent with what's already in the library.

Lysxia commented 5 years ago

I meant that now theInt typechecks, which removes the motivation for HasTypeConstraints.

LightAndLight commented 5 years ago

How confusing- the initial example does in fact compile. I'll revisit this tomorrow and see what I'm missing. I definitely encountered a problem in this area.

LightAndLight commented 5 years ago

I'm busy with other things so I'm going to close this. If I come across the issue again I'll re-open.