alphaHeavy / protobuf

An implementation of Google's Protocol Buffers in Haskell.
http://hackage.haskell.org/package/protobuf
BSD 3-Clause "New" or "Revised" License
96 stars 18 forks source link

Declaring Enumerations leading to type errors #2

Closed istathar closed 10 years ago

istathar commented 10 years ago

Been fascinating [trying] to use protobuf; first time I've ever seen type families being used for real. I'm a little stuck trying to use an enum, though. With code along the following lines:


{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS -fno-warn-unused-imports #-}

module Main where

import Data.Hex
import Data.Int (Int64)
import Data.Monoid (Monoid, mempty)
import Data.ProtocolBuffers
import Data.Serialize
import Data.Text (Text)
import Data.Typeable (Typeable)
import Data.TypeLevel (D1, D2)
import Data.Word (Word32, Word64)
import GHC.Generics (Generic)

data DataFrame = DataFrame {
    timestamp        :: Required D1 (Value Word64),
    valuetype        :: Required D2 (Enumeration ValueType),
} deriving (Generic, Show)

instance Encode DataFrame
instance Decode DataFrame

data ValueType
    = EMPTY
    | NUMBER
    | TEXT
    | REAL
  deriving (Enum, Generic, Bounded, Eq, Typeable) -- and 15 other things I've tried

instance Encode ValueType
instance Decode ValueType

instance Show ValueType

Gives an error of the form:

   No instance for (EncodeWire (Always (Enumeration ValueType)))
      arising from a use of `protobuf-0.1.1:Data.ProtocolBuffers.Encode.$gdmencode'
    Possible fix:
      add an instance declaration for
      (EncodeWire (Always (Enumeration ValueType)))
    In the expression:
      (protobuf-0.1.1:Data.ProtocolBuffers.Encode.$gdmencode)
    In an equation for `encode':
        encode = (protobuf-0.1.1:Data.ProtocolBuffers.Encode.$gdmencode)
    In the instance declaration for `Encode DataFrame'

which I'm not quite sure how to decipher. Without the enumeration it works very well indeed. I'm obviously missing something but it's not obvious to me what it is. Any suggestions would be welcome.

AfC

NathanHowell commented 10 years ago

I'll take a look, I don't think there is test coverage for the Enumeration support so it may well be broken for encoding.

istathar commented 10 years ago

tests/Main.hs line 140 seems to suggest you at least came close to testing it :)

NathanHowell commented 10 years ago

Indeed :-) I'll see if I can get a fix hacked together tonight. The rest of the code is tested and in production.

NathanHowell commented 10 years ago

Hmm... @sseveran reminded me that he's using Enumeration and the above code does compile on my dev box. Looks like this was added in 12697d5d1be73c8d686c704456954c0d369d0d0f (including tests) but not uploaded to Hackage. Could you check and see if this works for you? If so I'll tag and upload a new release.

istathar commented 10 years ago

@NathanHowell ok!

Built and installed from Git and indeed it compiles now. Yeay!

Now my problem is the program, instead of running as expected, outputs:

$ ./program
program: <<loop>>

+RTS -xc reports it's happening in Main.CAF. Not much help there. I am running GHC 7.6.3. Is that "too old", perhaps?

AfC

istathar commented 10 years ago

Forget that. Fixed!

I was playing with the derived classes, to see if something was up there. I tried dropping to

data ValueType
    = EMPTY
    | NUMBER
    | TEXT
    | REAL
  deriving (Enum, Generic)

no joy. Then, forgetting I had previously had to do:

instance Show ValueType

because the compiler had earlier told me to, I added Show to deriving:

data ValueType
    = EMPTY
    | NUMBER
    | TEXT
    | REAL
  deriving (Enum, Generic, Show)

which of course errorred. So I removed the manual declaration, and ta-da! Program works, protobuf is awesome, and order is returned to the galaxy.

Thanks for your help. Recommend a release!

AfC

NathanHowell commented 10 years ago

Awesome. I've tagged a new release and upload it to Hackage: http://hackage.haskell.org/package/protobuf-0.1.2. Thanks for the help :+1: