well-typed / generics-sop

Generic Programming using True Sums of Products
BSD 3-Clause "New" or "Revised" License
157 stars 48 forks source link

sop-core: Concatenate a POP into an NP #176

Open turion opened 11 months ago

turion commented 11 months ago

This may be out of scope, but I use sop-core as a lean, clean, principled general purpose library for heterogeneous sums and products. As such it is great, but sometimes I'm lacking a feature. For example, concatenation. For homogeneous lists, there is (++) :: [a] -> [a] -> [a] and concat :: [[a]] -> [a], but I believe this doesn't exist in sop-core. I think it should be possible to implement with these type signatures:

type family Concat (xss :: [[k]]) :: [k] where
  ...

hconcat :: POP f xss -> NP f (Concat xss)

Maybe it's already possible to do this with the existing type families, if so, I don't know how. In that case it might be helpful to add a type alias and a function to witness this.

Either way, if you think this works and is a good addition, I'll happily send a PR.

phadej commented 11 months ago

This is sibling issue to #115. See general comments there.

concat_NS :: NS (NS f) xss -> NS f (Concat xss) e.g. is a reasonable thing to have. And also the reverse functions, SListI2 xss => NP f (Concat xss) -> NP (NP f) xss, and a NS variant.

turion commented 11 months ago

@phadej I'd also be willing to co-maintain a sop-core-extras package with you.

phadej commented 11 months ago

I don't think anymore that sop-core-extras is a good idea. If a separate package were to be introduced, it would be one defining Append, Concat etc. (list related) type families (and if UnsaturatedTypeFamilies is implemented in GHC ,then Map etc higher-order type families too), and then sop-core could depend on it.

But for time being, IMO, they can be defined in sop-core too.

EDIT: e.g. optics-core defines own Append: https://hackage.haskell.org/package/optics-core-0.4.1.1/docs/Optics-Internal-Optic-TypeLevel.html#t:Append, so there is some value of having shared package for type-families, so they are not redefined in every package.

kosmikus commented 11 months ago

The problem is that there are so many ways to define even "simple" type families that the hope of actually being able to reuse them is nearly zero. See e.g. the "extra" case in Append in the linked optics-core which depending on use case, you may or may not want.

I'm still not extremely fond of adding more things for general-purpose programming to sop-core, but I've also already said in the past that I'm not going to block adding a few more functions if that's what everyone seems to want.

turion commented 11 months ago

I understand that you prefer to add only things to sop-core that can be used in generics-sop. But maybe Concat could be used for a generic "flatten a record of records" function? If yes, and this is desired, I'll try and add this as well, possibly with your guidance.

turion commented 11 months ago

The problem is that there are so many ways to define even "simple" type families that the hope of actually being able to reuse them is nearly zero.

I don't have enough experience to comment on that, I would have implemented it in the "vanilla" way, not being aware of particular downsides.

phadej commented 11 months ago

I needed Append and Concat for my own needs, and some other stuff so I ended up making https://hackage.haskell.org/package/defun-sop

There isn't split, unconcat or NS versions, as I'm yet not sure how I want them to look as (I try my best to avoid SListI, but sometimes it is convenient). However there are some definitions in https://github.com/phadej/defun/blob/master/defun/test/defun-tests.hs