No instance for (Constructor Main.D1MyData)

Dear list, I try to implement the generic show of section 3.6 from the paper Magelheas et al., "A Generic Deriving Mechanism for Haskell" but run into problems with the Constructor class. If someone could point out what is wrong here I would be most grateful. I import generics:
import GHC.Generics
And I define my own "Show" class named "Toonbaar", and a generic version of the class "GToonbaar":
class Toonbaar a where toon :: a -> String
default toon :: (Generic a, GToonbaar (Rep a)) => a -> String toon a = gtoon (from a)
instance Toonbaar Int where toon i = show i
class GToonbaar f where gtoon :: f a -> String
Next I want implement instances of gtoon for the 5 primitive types that are used to by the "from" function to represent data types. Most interisting is the meta-information instance here, where I use the "conName" function. Most of the rest I copied from the serialization example on the wiki: http://www.haskell.org/haskellwiki/GHC.Generics#Complete_working_example
-- | Meta-information (constructor names, etc.) instance (GToonbaar a, Constructor c) => GToonbaar (M1 i c a) where gtoon m@(M1 _) = conName m
-- | Unit: used for constructors without arguments instance GToonbaar U1 where gtoon _ = "Unit"
-- | Constants, additional parameters and recursion of kind * instance (GToonbaar a, GToonbaar b) => GToonbaar (a :*: b) where gtoon _ = "Constant"
-- | Sums: encode choice between constructors instance (GToonbaar a, GToonbaar b) => GToonbaar (a :+: b) where gtoon x = gtoon x
-- | Products: encode multiple arguments to constructors instance (Toonbaar a) => GToonbaar (K1 i a) where gtoon (K1 x) = toon x
I define a data type, deriving Generic and make it an instance of Toonbaar.
data MyData = MyInt Int deriving (Generic) instance Toonbaar MyData
main = putStrLn (toon (MyInt 42))
When I try to compile the above, ghc emits the following error: No instance for (Constructor Main.D1MyData) arising from a use of `Main.$gdmtoon' Possible fix: add an instance declaration for (Constructor Main.D1MyData) In the expression: (Main.$gdmtoon) In an equation for `toon': toon = (Main.$gdmtoon) In the instance declaration for `Toonbaar MyData' There are 2 things here that I do not understand: 1. I was under the impression that Constructor can be derived, but this does not seem to be the case. (I tried adding it to the line where I also derive Generic). Is there another way to derive it? 2. Why is the error message referring to D1MyData and not to MyData? And $gdmtoon instead of toon or gtoon? Thanks, Maarten

Hi Maarten, On Tue, Dec 10, 2013 at 3:48 PM, Maarten Faddegon < haskell-cafe@maartenfaddegon.nl> wrote:
Dear list,
-- | Meta-information (constructor names, etc.)
instance (GToonbaar a, Constructor c) => GToonbaar (M1 i c a) where
This is not good; an instance of |Constructor c| will only be available when your |M1 i c a| is actually |M1 C c a| (so |i ~ C|). In the other cases (that is, when |i| is either |D| or |S|), that instance will not exist (there will be |Datatype| and |Selector| instances, respectively). You can find a generic show using GHC.Generics here: http://hackage.haskell.org/package/generic-deriving-1.6.2/docs/src/Generics-...
-- | Sums: encode choice between constructors instance (GToonbaar a, GToonbaar b) => GToonbaar (a :+: b) where gtoon x = gtoon x
This will cause your code to loop, btw.
When I try to compile the above, ghc emits the following error:
No instance for (Constructor Main.D1MyData) arising from a use of `Main.$gdmtoon' Possible fix: add an instance declaration for (Constructor Main.D1MyData) In the expression: (Main.$gdmtoon) In an equation for `toon': toon = (Main.$gdmtoon) In the instance declaration for `Toonbaar MyData'
It's not the most beautiful of errors, but it does say that there is no |Constructor| instance for |D1MyData|, and |D1MyData| is the automatically generated datatype to encode the *datatype* meta-information for |MyData|. Hope that helps, Pedro
participants (2)
-
José Pedro Magalhães
-
Maarten Faddegon