Проблема с байтовой строкой библиотеки Haskell Aeson JSON

У меня возникли проблемы с поиском функции или обходного пути для преобразования String в Data.ByteString.Lazy.Internal.ByteString

Одна из функций в библиотеке Aeson Json называется decode и имеет следующее описание:

decode :: FromJSON a => bytestring-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString -> Maybe a

Я пытался использовать функцию pack в Data.ByteString.Lazy.Char8, но она возвращает другую ByteString. Кто-нибудь знает, как это можно исправить?

Ниже приведен пример, над которым я работаю:

import Data.Aeson
import Data.Text
import Control.Applicative
import Control.Monad (mzero)
import qualified Data.ByteString.Lazy.Internal as BLI
import qualified Data.ByteString.Lazy.Char8 as BSL

data Person = Person 
    { name :: Text
    , age :: Int 
    } deriving Show

instance FromJSON Person where 
    parseJSON (Object v) = Person <$>
                   v .: (pack "name") <*>
                   v .: (pack "age")
    parseJSON _          = mzero

Я попытался использовать decode (BSL.pack "{\"name\":\"Joe\",\"age\":12}") :: Maybe Person и получил следующее сообщение об ошибке:

Couldn't match expected type `bytestring-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString'
                with actual type `BSL.ByteString'
    In the return type of a call of `BSL.pack'
    In the first argument of `decode', namely
      `(BSL.pack "{\"name\":\"Joe\",\"age\":12}")'
    In the expression:
        decode (BSL.pack "{\"name\":\"Joe\",\"age\":12}") :: Maybe Person

Помощь!


person MathanMV    schedule 12.12.2013    source источник
comment
У вас установлено несколько версий bytestring? Попробуйте запустить ghc-pkg list bytestring для проверки.   -  person bennofs    schedule 13.12.2013
comment
В списке есть два элемента: bytestring-0.10.0.2 и bytestring-.10.4.0 — вызовет ли это проблему? Я знаю, что у меня была ошибка связывания GHCI ранее, когда я играл с кодом выше.   -  person MathanMV    schedule 13.12.2013
comment
Да, мне пришлось отменить регистрацию bytestring-10.4.0, чтобы заставить его работать.   -  person MathanMV    schedule 13.12.2013


Ответы (2)


Вам нужно преобразовать Char в Word8 с помощью c2w (в Data.ByteString.Internal)

Data.ByteString.Lazy.pack $ map c2w "abcd"

Я также написал полное имя для пакета, чтобы гарантировать использование правильного имени, но вы можете почистить это в разделе импорта. Когда я бегу

> :t Data.ByteString.Lazy.pack $ map c2w "abcd"

Я получаю ":: Data.ByteString.Lazy.Internal.ByteString"

Помните, что Data.ByteString.Lazy представляет строки числовых значений (вы даже не можете запустить его пакет на строках, вам нужно указать массив чисел «pack [1, 2, 3, 4]»), так что вы могли бы на самом деле хотите использовать эквивалент char Data.ByteString.Lazy.Char8.

person jamshidh    schedule 12.12.2013
comment
Мне удалось получить правильный тип, используя это. Итак, я получаю Data.ByteString.Lazy.Internal.ByteString, но теперь он запрашивает byteString-0.10.0.2:Data.ByteString.Lazy.Internal.ByteString. Хм, я думаю, это может быть проблемой, которую Бенноф прокомментировал в исходном сообщении, потому что у меня есть две версии строк байтов? - person MathanMV; 13.12.2013
comment
Вполне может быть проблема с версией, но помните, что даже в одной версии библиотек есть четыре строки байтов: strict/Word8, strict/Char8, lazy/Word8 и strict/Char8.... и пакет будет только напрямую работайте над строкой для версий Char8. - person jamshidh; 13.12.2013
comment
У Brilliant была еще одна проблема с установкой двух строк байтов, которая также была исправлена, как упоминалось в комментарии к исходному сообщению. Благодарю вас! - person MathanMV; 13.12.2013

Вы также можете использовать для удобства fromString из Data.ByteString.Lazy.UTF8 из utf8-string.

Это модуль функций для того же типа ByteString, который использует aeson. Он использует UTF8 как кодировку, используемую в буферах.

person imz -- Ivan Zakharyaschev    schedule 30.03.2015