0

I'm trying to simplify a composite data type, but don't know the best way. Here is my code so far:

data Init a b c d = Init a b c d

data Wrap a = WNil (Init a b c d)
            | WCons a (Wrap a)

The issue I keep seeing is probably obvious - I can't unify the expected result type's type variables with the encapsulated one:

-- | Will fail to compile
unWrap :: Wrap a -> Init a b c d
unWrap (WNil x) = x
unWrap (WCons _ xs) = unWrap xs

I've heard -XExistentialQuantification thrown around as a possible solution, but I couldn't get anything working. Does anyone have an idea what to do here, besides floating the type parameters to Wrap?

Athan Clark
  • 3,886
  • 2
  • 21
  • 39
  • 4
    It's unfortunately very unclear what you want. Why is floating the type parameters to `Wrap` not an option? If `a`, `b`, `c`, and `d` are really independent and flexible, it seems like the right thing to do. Even if you used existential quantification, you'd know nothing about the hidden types and couldn't do anything useful with them. – kosmikus Jan 20 '15 at 20:39
  • @kosmikus: So they're not actually independent and flexible. I'm doing a lot of type-level programming, so having them as universally quantified solves my heterogeneity problem :\ In this example, `b, c, d` are auxilliary types facilitating some internal plumbing for the type safety. The thing is, though, once I create `Init`, the types are no longer prone to change, and that's why I feel comfortable "wrapping" them away. – Athan Clark Jan 20 '15 at 21:04
  • 2
    @AthanClark once you place `Init` in an existential wrapper, you can do absolutely nothing with the `b c d` fields, it's pretty much throwing them into a black hole. Existentials are only useful if there are additional data wrapped in, like class instances, functions or singletons. – András Kovács Jan 20 '15 at 21:26
  • 1
    You can't throw `b,c,d` away and get get them back. At most, your `unWrap` function can temporarily get them back only to rewrap them into a new existential-type container, or pass them to a polymorhic countinuation e.g. `unWrap :: Wrap a -> (forall b c d. Init a b c d -> r) -> r`. – chi Jan 20 '15 at 21:50
  • 1
    Also, I can't see how the title of the question relates to the actual question. Tags also agree with the title, only. Can you shed some light or edit them to be more relevant? – chi Jan 20 '15 at 21:52
  • 6
    I think the clarity of this question would really benefit if you included the actual problem you were trying to solve. – user2407038 Jan 20 '15 at 22:04

0 Answers0