9

I've been toying around with -XDataKinds recently, and was wondering why Foo below won't be automatically promoted:

{-# LANGUAGE
    GADTs
  , DataKinds
  , KindSignatures #-}

import Data.HList

data Foo a where
  Foo :: Bar a =>
         a -> Foo a

data Baz where
  Baz :: (a ~ HList (l :: [Foo *])) =>
         a -> Baz

That is, Baz is a heterogenous list of Foo a's, where a is constrained by Bar.

Is there a way to manually create a promoted version of this data type? How would I go about doing so? Can kinds be declared? Could I make a dummy Haskell98 version of Foo, and separate it into a module or something? Ideally I'd like to keep the constraint context, but I don't think there's a Constraint sort. Any ideas would be very helpful!

Athan Clark
  • 3,886
  • 2
  • 21
  • 39
  • I'm wondering if I could just (somehow) declare a kind, then make `Foo` the only inhabitant of it. – Athan Clark Dec 17 '14 at 15:23
  • 2
    With some small changes I got [this](https://gist.github.com/ec1ab70974c4d6d7f6b9) to work. Is that the kind of thing you're looking for? I can't explain why it works, but it does compile. – bheklilr Dec 17 '14 at 16:11
  • 1
    Ahh, you're very correct, this is exactly what I needed. The kind signature wasn't necessary! – Athan Clark Dec 17 '14 at 16:48
  • 1
    I also had to change it to `'[]` instead, but again I don't know enough about `DataKinds` to tell you why this version works in particular. – bheklilr Dec 17 '14 at 16:51
  • 5
    `Foo` is unpromotable, since GADTs in general are unpromotable (in this specific case, it is because of the constraint). If you try `:kind! 'Foo` in ghci, you will see this. `Foo` refers to the type constructor `Foo`, not the data constructor, when used in `Baz`. Although `Baz` is a very boring type because `HList ('[Foo b])` is essentially just `Foo b`, and `b` is existentially quantified so `Baz` is equivalent to `data Baz = forall a . Bar a => Baz a`. I don't know if this is what you want, but somehow I doubt it. – user2407038 Dec 17 '14 at 17:22
  • @user2407038 You're right, I didn't realize `'[Foo b]` was a singleton. Crud. Back to the drawing board. – Athan Clark Dec 17 '14 at 17:34
  • @AthanClark If you need a heterogeneous list of types each of which satisfies some constraint, just have an `HList` and a class which recurses through the list and does whatever to each element. – user2407038 Dec 17 '14 at 18:26
  • @user2407038 Something that worked for me, actually was to put a kind signature on `l`, like in my question, but make it higher kinded, then supply a parameter `b` and bind it to `FooLike a`. Phew! @bheklilr Would you like to issue the answer? – Athan Clark Dec 17 '14 at 18:35

0 Answers0