2021年1月28日星期四

How to write a Serialize instance for this GADT?

Below is a module that attempts to implement a Serialize instance for a simple GADT. Unfortunately the get implementation for the Reorder constructor complains that there is no Ixed a constraint. Is there any way, beautiful or ugly, to implement this? I can't add Ixed a to the instance context because the Update constructor needs to work for values that don't satisfy this constraint.

{-# LANGUAGE GADTs #-}    import Control.Lens (Index, Ixed)  import Data.Serialize    -- | Two different ways of updating a value - replacing it completely or,  -- if it is an instance of Ixed, re-ordering it.  data Op a where    Update :: Serialize a => a -> Op a    Reorder :: (Ixed a, Serialize (Index a)) => [Index a] -> Op a    instance Serialize a => Serialize (Op a) where    put (Update a) = putWord8 1 >> put a    put (Reorder ks) = putWord8 2 >> put ks    get = do      i <- getWord8      case i of        1 -> Update <$> get        2 -> Reorder <$> get        _ -> error "instance Serialize (Op a) - corrupt data"  

Addendum: One simplification to this might be to make the type variable a a phantom type, so that Op looks like this:

data Op a where    Update :: Serialize a => ByteString -> Op a    Reorder :: (Ixed a, Serialize (Index a)) => [ByteString] -> Op a  

The type could then be used to properly decode the byte strings. Not sure whether this helps

https://stackoverflow.com/questions/65941212/how-to-write-a-serialize-instance-for-this-gadt January 29, 2021 at 12:25AM

没有评论:

发表评论