Closed masaeedu closed 4 years ago
The end markers are actually necessary for being able to properly iterate through the structure of the ADTs. Consider this example:
{-# LANGUAGE DeriveGeneric #-}
import Generics.Eot
data Foo = Foo Int Int
deriving (Generic)
data Bar = Bar (Int, Int)
deriving (Generic)
In the current implementation, i.e. with end markers you get:
Eot Foo ~ Either (Int, (Int, ())) Void
Eot Bar ~ Either ((Int, Int), ()) Void
With these types generic code can distinguish between tuples in fields in tuples stemming from Eot
. And for some generic code that is essential. Imagine for example a serialization library that wants to preserve the tree structure of the data as it exists in the haskell types.
If I understand you right, what you're proposing is to have Eot
behave like this:
Eot Foo ~ (Int, Int)
Eot Bar ~ (Int, Int)
Which then wouldn't allow to treat Foo
and Bar
differently any more. That's why these end markers exist.
I believe you can construct a similar example for the Void
end marker.
I think what you want can be implemented on top of generics-eot
. Although if you already have a working implementation on top of generics-sop
there's no good reason to switch.
@soenkehahn That's a good point, I hadn't considered that use case. You did understand my proposal correctly; for my use case I need to eliminate the distinction between those two representations so the user doesn't need to worry about what the exact data type is, so long as they can build up something that contains the equivalent data.
You're right again about being able to build what I want on top of generics-eot
, in fact the ENormalize
class in the link I provided does exactly that. It takes an either-of-tuples representation with end markers that's identical to what you get from eot and then provides an isomorphism to a representation lacking the end markers. My suggestion was to roll this into eot, but now I see this doesn't quite satisfy all the use cases the library supports.
Hello. I found this library because I needed something very similar to it, but unfortunately my use case prevented me from being able to use a type with extra
()
s andVoid
s. So for example for the type:I need:
instead of:
I tried seeing if the former behavior could be implemented, and while it's not fun, I was able to build it on top of
generics-sop
. You can see the results here.Here's what using it looks like:
Would you be interested in a change to this library that makes it behave in a similar fashion? I understand that this is a big breaking change and maybe your use case actually intentionally prefers the end markers, but I thought I'd check anyway.