如何派生 Data.Messagepack 1.0.0 的实例
How to derive instances of Data.Messagepack 1.0.0
上一版本Data.Messagepack
,0.7.2.5 supports deriving instances via Template Haskell. The current version (1.0.0), however, doesn't.
因此我想知道是否有另一种方法可以自动派生 MessagePack 1.0.0 实例,可能使用 XDeriveGeneric
?
作为权宜之计,请查看 message-pack
github 存储库的 msgpack-aeson
目录:
https://github.com/msgpack/msgpack-haskell/tree/master/msgpack-aeson
您可以从您的数据值 <-> aeson <-> 消息包。不一定高效,但方便,因为您可以使用 DeriveGeneric
.
自动派生 ToJSON 和 FromJSON
示例代码:
{-# 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")
您可以编写自己的 GMessagePack
class 并通过派生 Generic
来获取实例。我试着这样做来回答这个问题,但我不推荐它。 msgpack 不支持求和,并且 one sum type supported by the Haskell msgpack library, Maybe
的编码非常差。
instance MessagePack a => MessagePack (Maybe a) where
toObject = \case
Just a -> toObject a
Nothing -> ObjectNil
fromObject = \case
ObjectNil -> Just Nothing
obj -> fromObject obj
Maybe
的编码无法区分Nothing :: Maybe (Maybe a)
和Just Nothing :: Maybe (Maybe a)
,两者都会被编码为ObjectNil
,解码为Nothing
.如果我们要将显而易见的定律 fromObject . toObject == pure
强加给 MessagePack
个实例,MessagePack
的这个实例就会违反它。
上一版本Data.Messagepack
,0.7.2.5 supports deriving instances via Template Haskell. The current version (1.0.0), however, doesn't.
因此我想知道是否有另一种方法可以自动派生 MessagePack 1.0.0 实例,可能使用 XDeriveGeneric
?
作为权宜之计,请查看 message-pack
github 存储库的 msgpack-aeson
目录:
https://github.com/msgpack/msgpack-haskell/tree/master/msgpack-aeson
您可以从您的数据值 <-> aeson <-> 消息包。不一定高效,但方便,因为您可以使用 DeriveGeneric
.
示例代码:
{-# 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")
您可以编写自己的 GMessagePack
class 并通过派生 Generic
来获取实例。我试着这样做来回答这个问题,但我不推荐它。 msgpack 不支持求和,并且 one sum type supported by the Haskell msgpack library, Maybe
的编码非常差。
instance MessagePack a => MessagePack (Maybe a) where
toObject = \case
Just a -> toObject a
Nothing -> ObjectNil
fromObject = \case
ObjectNil -> Just Nothing
obj -> fromObject obj
Maybe
的编码无法区分Nothing :: Maybe (Maybe a)
和Just Nothing :: Maybe (Maybe a)
,两者都会被编码为ObjectNil
,解码为Nothing
.如果我们要将显而易见的定律 fromObject . toObject == pure
强加给 MessagePack
个实例,MessagePack
的这个实例就会违反它。