Haskell, Aeson — нет экземпляра для (ToJSON ByteString)

Так счастлив, что зашел так далеко, что столкнулся с новым препятствием: получил этот код для кодирования в JSON. Однако независимо от того, какой тип я использую в качестве экземпляра, компилятор жалуется. Теперь я явно делаю что-то не так, но это именно то, что есть в документации (очевидно, при использовании DeriveGeneric).

{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}

import Data.Aeson
import Data.Text as T
import Data.ByteString.Lazy as B
import Data.ByteString.Lazy.Char8 as BC
import GHC.Generics

-- decode :: FromJSON a => B.ByteString -> Maybe a
-- decode' :: FromJSON a => B.ByteString -> Either String a
-- encode :: ToJSON => a -> B.ByteString

data System = System  { system :: BC.ByteString
                  , make :: BC.ByteString
                  , code :: Int
                  } deriving (Generic, Show)
instance ToJSON System
-- instance FromJSON System

platform = System { system = "FPGA"
                  , make = "Xilinx"
                  , code = 10165
                  }
encodePlatform :: BC.ByteString
encodePlatform = encode platform

Вывод компилятора:

    • No instance for (ToJSON ByteString)
        arising from a use of ‘aeson-1.4.1.0:Data.Aeson.Types.ToJSON.$dmtoJSON’
    • In the expression:
        aeson-1.4.1.0:Data.Aeson.Types.ToJSON.$dmtoJSON @(System)
      In an equation for ‘toJSON’:
          toJSON = aeson-1.4.1.0:Data.Aeson.Types.ToJSON.$dmtoJSON @(System)
      In the instance declaration for ‘ToJSON System’
   |
17 | instance ToJSON System

person Madderote    schedule 14.11.2018    source источник
comment
Если ByteString здесь действительно правильный тип, то вам, вероятно, не следует преобразовывать его в JSON. Вместо этого используйте двоичную сериализацию. Если эти поля на самом деле содержат текст, а не двоичные данные, сделайте тип Text. Если они содержат двоичные данные, но вам нужно использовать JSON, используйте base64 или что-то в этом роде.   -  person leftaroundabout    schedule 14.11.2018


Ответы (1)


Это потому, что нет экземпляра ByteString для класса типов ToJSON. Исторически он присутствовал, но был удален, потому что строки JSON должны быть действительными юникодами.

Вы можете найти более подробную информацию здесь:

Чтобы исправить это, я бы преобразовал его в тип Text, а затем закодировал в JSON.

person Sibi    schedule 14.11.2018