问题
The previous version of Data.Messagepack, 0.7.2.5 supports deriving instances via Template Haskell. The current version (1.0.0), however, doesn't.
I was hence wondering if there is an alternative way to automatically derive MessagePack 1.0.0 instances, possibly using XDeriveGeneric?
回答1:
As a stop-gap measure, have a look at the msgpack-aeson directory of the message-pack github repo:
https://github.com/msgpack/msgpack-haskell/tree/master/msgpack-aeson
You could go from your data values <-> aeson <-> message-pack. Not necessarily efficient, but convenient since you can auto derive ToJSON and FromJSON with DeriveGeneric.
Example code:
{-# LANGUAGE DeriveGeneric, OverloadedStrings #-}
import Data.MessagePack.Aeson
import qualified Data.MessagePack as MP
import GHC.Generics
import Data.Aeson
data Foo = Foo { _a :: Int, _b :: String }
deriving (Generic)
instance ToJSON Foo
instance FromJSON Foo
toMsgPack :: Foo -> Maybe MP.Object
toMsgPack = decode . encode
test = toMsgPack (Foo 3 "asd")
回答2:
You could write your own GMessagePack class and get instances by deriving Generic. I tried doing so to answer this question, but I can't recommend it. msgpack has no support for sums, and the one sum type supported by the Haskell msgpack library, Maybe, has a very poor encoding.
instance MessagePack a => MessagePack (Maybe a) where
toObject = \case
Just a -> toObject a
Nothing -> ObjectNil
fromObject = \case
ObjectNil -> Just Nothing
obj -> fromObject obj
The encoding for Maybes can't tell the difference between Nothing :: Maybe (Maybe a) and Just Nothing :: Maybe (Maybe a), both will be encoded as ObjectNil and decoded as Nothing. If we were to impose on MessagePack instances the obvious law fromObject . toObject == pure, this instance for MessagePack would violate it.
来源:https://stackoverflow.com/questions/31892857/how-to-derive-instances-of-data-messagepack-1-0-0