Обычно я знаю, как исправить неоднозначные переменные типа, но не в этот раз. Короче говоря, я использую protobuf Библиотека Haskell для работы с protocol buffers. Библиотека заставляет вас забыть о сохранении отдельных файлов .proto, она выводит способ сериализации и десериализации вашего типа данных, если это экземпляр классов типа Encode и Decode соответственно.Haskell protobuf: неоднозначная переменная типа
Я разрабатываю простой протокол поверх протобуфа. Существует тип данных основного сообщения, содержащий идентификатор сообщения, тип сообщения и некоторые дополнительные данные, которые зависят от типа. Я хочу иметь функцию, которая получает идентификатор сообщения, тип сообщения и необязательные данные (который должен быть экземпляром класса Encode) и заранее создает новый экземпляр MyMessage с необязательными данными, сериализованными в ByteString.
Вот как я пытаюсь сделать это:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneriC#-}
import Data.ByteString (ByteString)
import Data.Int
import Data.Maybe
import Data.Monoid
import Data.ProtocolBuffers
import Data.Serialize
import Data.Text (Text, pack)
import GHC.Generics (Generic)
import GHC.TypeLits
data MyMsgType = MSG_TYPE_1
| MSG_TYPE_2
deriving (Enum, Show)
data MyMessage = MyMessage {
msgId :: Required 1 (Value Int64)
, msgType :: Required 2 (Enumeration MyMsgType)
, cpData :: Optional 3 (Value ByteString)
} deriving (Generic, Show)
instance Encode MyMessage
instance Decode MyMessage
createMessage :: Encode a => Int64 -> MyMsgType -> Maybe a -> MyMessage
createMessage msgId msgType optionalData =
MyMessage (putField msgId) (putField msgType) (putField $ serialiseOptionalData optionalData)
serialiseMessage :: MyMessage -> ByteString
serialiseMessage = runPut . encodeLengthPrefixedMessage
serialiseOptionalData :: Encode a => Maybe a -> Maybe ByteString
serialiseOptionalData Nothing = Nothing
serialiseOptionalData (Just ctx) =
Just . runPut . encodeLengthPrefixedMessage $ ctx
Когда я пытаюсь использовать функцию createMessage я получаю следующее сообщение об ошибке:
λ> createMessage 1 MSG_TYPE_1 Nothing
<interactive>:7:1:
No instance for (Encode a0) arising from a use of ‘createMessage’
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
instance Encode MyMessage -- Defined at test.hs:24:10
instance Encode
(unordered-containers-0.2.6.0:Data.HashMap.Base.HashMap
protobuf-0.2.1.0:Data.ProtocolBuffers.Wire.Tag
[protobuf-0.2.1.0:Data.ProtocolBuffers.Wire.WireField])
-- Defined in ‘protobuf-0.2.1.0:Data.ProtocolBuffers.Encode’
In the expression: createMessage 1 MSG_TYPE_1 Nothing
In an equation for ‘it’: it = createMessage 1 MSG_TYPE_1 Nothing
Может кто-нибудь объяснить мне, почему возникает эта ошибка и как ее исправить Это? Я не понимаю, где именно компилятор видит двусмысленность.
cheers mate, вы не можете себе представить, сколько времени я потратил, пытаясь выяснить, что не так :) –