63

I had this code:

class SymbolSet tpe where
  data Symbol tpe :: *

data SSet tpe where
  Identity :: tpe -> SSet tpe
  And :: SSet tpe -> Symbol tpe -> SSet tpe

class HasElem a b where

instance (SymbolSet tpe) => HasElem (And (Identity tpe) s) s
instance (HasElem sset s) => HasElem (And sset s) s

which was compiling in GHC-7.4. However on moving to GHC-7.6 it started giving compilation errors:

'And' of tpe `forall tpe. tpe -> Symbol * tpe -> SSet tpe' is not promotable

on digging through the docs, I found a new clause added to "Datatype Promotion" pages in GHC-7.6 vs GHC-7.4

We do not promote datatypes whose constructors are kind polymorphic, involve constraints, or use existential quantification.

My question is:

  1. What is the rationale behind not promoting such constructors?
  2. What would be the correct way of doing it?
crockeea
  • 21,651
  • 10
  • 48
  • 101
rabisg
  • 731
  • 4
  • 6
  • 1
    To the second question: I think the problem is that the `SSet(And)` constructor have data family (namely `Symbol`) in its fields. At least, the problem persist even if I explicitly restrict kinds to `*` by additional kind annotations. So the reason of the compilation error is not poly kinds probably. – Samvel Truzyan Nov 09 '13 at 18:42
  • Well, as I said I had the exact same code working in GHC-7.4. Well almost same since I edited it for making it more meaningful here. I currently dont have access to a machine with 7.4 installed but I'll try to verify it asap. – rabisg Nov 09 '13 at 19:45
  • I think you should report a bug that the error message does not give a reason *why* the constructor is not promotable. – SamB Jan 10 '14 at 21:48
  • I am interested in the answer too. Little off the topic, I am also interested in knowing how HasElem is intended to be used! That may help formulating a different solution. – Yogesh Sajanikar Jan 14 '14 at 16:45
  • I have some problems with the HasElem I have something like it... I keep waiting... – Robert Jan 20 '14 at 20:03

1 Answers1

1

You didn't say which version of GHC 7.6 you were using or include which extensions you have on, so I'm guessing a bit.

This ticket seems to answer your question 1, although I don't totally understand the problem myself. In your particular example, I think SSet isn't promotable because one of its arguments (Symbol tpe) is an associated type which brings with it the SymbolSet constraint.

If I move Symbol out of the class we get the type promoted, however now we get kind mismatch errors:

{-# LANGUAGE DataKinds , TypeFamilies , GADTs , MultiParamTypeClasses #-}
class SymbolSet tpe where
  -- data Symbol tpe :: *
data Symbol tpe :: *
-- ...

I can get the whole shebang to compile by adding kind signatures to HasElem:

{-# LANGUAGE DataKinds , TypeFamilies , GADTs , MultiParamTypeClasses, FlexibleInstances  #-}
class SymbolSet tpe where
-- MOVED OUT OF CLASS:
data Symbol tpe :: *

data SSet tpe where
  Identity :: tpe -> SSet tpe
  And :: SSet tpe -> Symbol tpe -> SSet tpe

-- ADDED KIND SIGNATURES:
class HasElem (a :: SSet *) (b :: Symbol *) where

instance (SymbolSet tpe) => HasElem (And (Identity tpe) s) s
instance (HasElem sset s) => HasElem (And sset s) s

I don't really understand your code so that may not work for you.

jberryman
  • 16,334
  • 5
  • 42
  • 83
  • I actually wanted `Symbol tpe` to be an associated data type because I was using it later in some way. Frankly, it has been quite some time since I asked this question and so I don't remember the specifics. Thanks for the the ticket link. I had seen it earlier but did not really understand the problem. It would be great if someone actually explains the ticket :) – rabisg Feb 16 '14 at 00:01