ekmett / bytes

Serialization primitives that work with both cereal and binary.
http://hackage.haskell.org/package/bytes
Other
22 stars 13 forks source link

It's impossible to define Serial1 instace for recursive data typesusing generics #21

Closed Shimuuar closed 8 years ago

Shimuuar commented 9 years ago

Current implementation cannot derive Serial1 instance for recursive data types. For example:

{-# LANGUAGE DeriveGeneric #-}
module Test where

import Data.Bytes.Serial
import GHC.Generics

data Tree a
  = Leaf a
  | Node (Tree a) (Tree a)
  deriving (Show,Eq,Generic,Generic1)

instance Serial1 Tree

fails to compile with following error message

bytes.hs:12:10:
    Could not deduce (GSerial1 Tree)
      arising from a use of ‘Data.Bytes.Serial.$gdmserializeWith’
    from the context (Data.Bytes.Put.MonadPut m)
      bound by the type signature for
                 serializeWith :: Data.Bytes.Put.MonadPut m =>
                                  (a -> m ()) -> Tree a -> m ()
      at bytes.hs:12:10-21
    In the expression: Data.Bytes.Serial.$gdmserializeWith
    In an equation for ‘serializeWith’:
        serializeWith = Data.Bytes.Serial.$gdmserializeWith
    In the instance declaration for ‘Serial1 Tree’
...

Note that for nonrecursive data types deriving works just fine. It appears that problem lies with instance for Rec1. It requires constraint GSerial1 fbut f is original data type and not its generic representation.

I'm not entirely sure this is correct. I've never used Generic1 type class before. I tested generic instance for Tree data type above and it does work correctly.

glguy commented 8 years ago

This seems like the right change, but I'm on my phone so I'll take a closer look later.