2015-03-30 3 views
1

У меня есть следующий код (который должен разобрать очень тривиальный { "url": "http://some.url.here/" } хэш):избежать строк туда-обратно в эсон

import   Control.Applicative 
import qualified Data.ByteString  as B 
import   Data.ByteString.Char8 (pack) 


import   Data.Aeson   () 
import   Data.Aeson.Types 



newtype SetNextUrl = SetNextUrl B.ByteString 

instance FromJSON SetNextUrl where 
    parseJSON (Object v) = SetNextUrl <$> 
     (pack <$> v .: "url") 

Теперь обратите внимание, что я намекал, что «URL» имеет тип String, используя pack ... Это, конечно, вызовет некоторые накладные расходы на преобразование: от входного байтового столбца до [Char] и обратно ....

Вопрос: Как я могу попросить Эзона интерпретировать поле «url» как байтовой строки?

ответ

4

aeson использует Text внутренне для строковых значений, так что если вы используете Data.Text.Encoding.encodeUtf8 вы не будете иметь Text -> String -> ByteString преобразования, это будет просто идти прямо из Text -> ByteString (что IIRC довольно дешево)

+0

Спасибо! Я, вероятно, должен был использовать Text в других местах, а ByteString - меньше ... Но ваше решение отлично! – dsign

+0

@dsign Вы должны использовать то, что более подходит для вашего приложения. Если вы манипулируете фактическими байтами, тогда используйте ByteString, это его работа. По сути, это «Вектор Word8» под капотом. Если вы работаете с данными только ASCII, тогда это подходит. Если вы работаете с действительно читаемым человеком/записываемым текстом, используйте текст. Он обрабатывает все жесткие части кодировки для вас. Если вы хотите поместить ByteStrings в файл JSON, возможно, вам стоит взглянуть на [BSON] (http://bsonspec.org/). – bheklilr

+0

@bheklilr Это очень хороший момент и причина, по которой я написал свой комментарий ... Я использовал ByteStrings ala Python 2.x str: как для unicode, так и для байтов .... Некоторые из этих применений скорее должны быть Texts. – dsign