экземпляр toJson одно значение - PullRequest
0 голосов
/ 30 ноября 2018

Я могу json-кодировать свои данные

import Data.Aeson                       (ToJSON, toJSON, (.=), object)
import qualified Data.Text      as T
import qualified Data.Text.Lazy as L

data ServiceResponse = ReadServiceResponse  L.Text
                     | GenericServiceError  Int L.Text

instance ToJSON ServiceResponse where
    toJSON (ReadServiceResponse text)      = object ["text" .= text]
    toJSON (GenericServiceError code text) =
        object ["code" .= code, "message" .= text]

Для данных, имеющих только одно "скалярное" значение (например, String, Int, L.Text, ...), я хотел бы получитьскалярное представление вместо объекта.Например, ReadServiceResponse должен быть закодирован в строку json вместо объекта, подобного

{
    text: "hi I'm some text."
}

Я пытался

instance ToJSON ServiceResponse where
    toJSON (ReadServiceResponse text) = text

, который не компилируется

• Couldn't match expected type ‘aeson-1.3.1.1:Data.Aeson.Types.Internal.Value’ with actual type ‘L.Text’

Должен ли я преобразовать text в Data.Aeson.Types.Internal.Value (Как я могу это сделать)?Заранее благодарен за любую помощь

1 Ответ

0 голосов
/ 30 ноября 2018

Поскольку toJSON должен возвращать значение типа Value, вы не можете вернуть text самостоятельно;он должен быть заключен в конструктор данных String.

toJSON (ReadServiceResponse text) = String text

Обратите внимание, что начиная с String :: T.Text -> Value, для этого необходимо использовать строгую реализацию Text в определении ReadServiceResopnse:

data ServiceResponse = ReadServiceResponse  T.Text -- not L.Text
                     | GenericServiceError  Int L.Text

или преобразование в toJSON:

toJSON (ReadServiceResponse text) = String . T.pack . L.unpack $ text
...