问题
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 Maybe
s 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