love-haskell / coercible-utils

Utility functions for Coercible types
https://hackage.haskell.org/package/coercible-utils
BSD 3-Clause "New" or "Revised" License
9 stars 3 forks source link

Packer/unpacker chains #40

Open treeowl opened 4 years ago

treeowl commented 4 years ago

With the old API, we could write things like ala (Product . getSum). With the new API, that's impossible. But can we do something similar with a somewhat similar API? The o `to` n argument in the Newtype module is a type-level specification of the relationship between o and n. Since it stands in for a function, it has no extra structure to offer. But what if we don't have that requirement? What if we had something more like

ala :: (Relationship to a b, Relationship to a' b', SimilarIn to a a', SimilarOut to b b')  => a `to` b -> ((a -> b) -> q -> b') -> q -> a'

Now to can have some structure reflecting how to get from a to b, and from that we can calculate what is expected to be similar to what. Totally bonkers, yes, but I'd like to see if it's possible. I think it'd need its own module tov protect the innocent.

kozross commented 4 years ago

@treeowl Does this also address my described concerns from here? Assuming it can be made to work, that is.

treeowl commented 4 years ago

I doubt it. The general shapes stay the same.

On Fri, Sep 20, 2019, 7:53 PM Koz Ross notifications@github.com wrote:

@treeowl https://github.com/treeowl Does this also address my described concerns from here https://github.com/love-haskell/coercible-utils/issues/24#issuecomment-530215170? Assuming it can be made to work, that is.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/love-haskell/coercible-utils/issues/40?email_source=notifications&email_token=AAOOF7PLDHJMOKI6KPNGYB3QKVO6DA5CNFSM4IY32ZGKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7IFIPI#issuecomment-533746749, or mute the thread https://github.com/notifications/unsubscribe-auth/AAOOF7L2APB5TLKDVTKCOELQKVO6DANCNFSM4IY32ZGA .

treeowl commented 4 years ago

I have a very rough draft of this idea I'll try to put online tomorrow. Thus far, it's rather awkward, but it seems to work. Inference is inherently a bit worse than for the Newtype module, but still pretty useful. There don't seem to be any analogues of pack or unpack. The gist is that whereas in the classic API you'd write something like ala (Product . getSum), here you'd need to write something like ala (Product `dot` get Sum). No, that's not a typo; get is a function.

treeowl commented 4 years ago

Another idea to explore is composed packers only. That's potentially much less awkward, because the whole chain can be inferred from a plain function.

treeowl commented 4 years ago

Ugh..... The composed-packers-only idea seems to produce a horrible mess. The only way to (maybe) make it work reasonably well is to replace some type families with classes that have overlapping instances. The basic problem is that when GHC does type family reduction, it doesn't admit a rule that Con x ≠ x for fear that x could be an infinite type. So it doesn't know when to stop opening up newtypes until their contents are monomorphic. Yuck. But the overlapping instance approach isn't working for me yet, and if it ever does I will be quite surprised if :t or error messages will even tell the truth, let alone be useful. So maybe the chain style, awkward as it is, is the best path in this direction.

kozross commented 4 years ago

I am strongly not in favour of overlapping instances, not least of all for the reasons you've just described.