【问题标题】:How to derive instances of Data.Messagepack 1.0.0如何派生 Data.Messagepack 1.0.0 的实例
【发布时间】:2015-08-08 11:55:30
【问题描述】:

Data.Messagepack0.7.2.5之前的版本支持deriving instances via Template Haskell。但是,当前版本 (1.0.0),doesn't

因此我想知道是否有另一种方法可以自动派生 MessagePack 1.0.0 实例,可能使用XDeriveGeneric

【问题讨论】:

    标签: haskell msgpack


    【解决方案1】:

    作为权宜之计,请查看message-pack github repo 的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")
    

    【讨论】:

    • 能否请您提供一些示例代码如何做到这一点?
    【解决方案2】:

    您可以编写自己的GMessagePack 类并通过派生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
    

    Maybes 的编码无法区分Nothing :: Maybe (Maybe a)Just Nothing :: Maybe (Maybe a),两者都将编码为ObjectNil,解码为Nothing。如果我们要对MessagePack 实例施加明显的法律fromObject . toObject == pure,那么MessagePack 的这个实例就会违反它。

    【讨论】:

    • 不幸的是,它是用于使用另一种语言编写的程序进行操作,甚至不支持 sum 类型,因此在这种情况下,它们的缺乏并不是一个重要的问题。
    • 我没有为此编写的通用类将是stackoverflow.com/q/32107706/414413的答案
    猜你喜欢
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-12
    • 2012-10-20
    • 2020-04-07
    相关资源
    最近更新 更多