2015-03-10 4 views
2

Интересно, почему Data.ByteString.Lazy.putStrLn устарел, но Data.ByteString.Lazy.putStr и Data.ByteString.Lazy.hPutStr нет?Каковы более безопасные и правильные альтернативы устаревшему `Data.ByteString.Lazy.putStrLn` и почему?

-- | A synonym for @[email protected], for compatibility 
-- 
hPutStr :: Handle -> ByteString -> IO() 
hPutStr = hPut 

-- | Write a ByteString to stdout 
putStr :: ByteString -> IO() 
putStr = hPut stdout 

-- | Write a ByteString to stdout, appending a newline byte 
-- 
putStrLn :: ByteString -> IO() 
putStrLn ps = hPut stdout ps >> hPut stdout (singleton 0x0a) 

{-# DEPRECATED putStrLn 
"Use Data.ByteString.Lazy.Char8.putStrLn instead. (Functions that rely on ASCII encodings belong in Data.ByteString.Lazy.Char8)" 
    #-} 

-- | The interact function takes a function of type @ByteString -> [email protected] 
-- as its argument. The entire input from the standard input device is passed 
-- to this function as its argument, and the resulting string is output on the 
-- standard output device. 

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

Но тогда это должно применяться ко всем этим функциям.

Теперь я подозреваю, что причиной является только символ новой строки с учетом этой функции.

Тогда я мог бы просто сделать

Data.ByteString.Lazy.putStr myString >> System.IO.putStrLn "" 

и чувствовать себя в безопасности о не потерять информацию, делая вывод?

Вариант .Char8 чувствует себя как-то опасным.

ответ

2

Устаревший putStrLn предполагает, что он знает, как кодировать символ '\n'. Ни одна из других функций, которые вы указали, не предполагает ничего о кодировании; они просто передают байты, которые вы передаете им. (Это ваша работа, чтобы гарантировать, что эти байты верны для кодировки, которую вы собираетесь использовать.) Я согласен с тем, что модуль .Char8 не так жаркий - он использует всю кодировку latin1, которая не проходит тест 21-го века. Вы считаете этот код:

ByteString.putStr myString >> System.IO.putStrLn "" 

Я не рекомендую это: это дает возможность иметь несоответствие между кодированием, который вы использовали для построения myString и кодирования, что System.IO.putStrLn использует. Вместо этого убедитесь, что myString имеет в конце кодированную строку новой строки.

+0

В моем случае я печатаю закодированный JSON (для большей части отладки). И я ошеломлен предупреждением компилятора об устаревании. Добавление новой строки к функции построения ('encode :: (ToJSON a) => a -> ByteString') вообще не доступно. Теперь, по крайней мере, теперь я являюсь основной проблемой, поэтому я не буду бояться использовать ByteString везде. –

+0

@ imz - IvanZakharyaschev Добавление новой строки должно быть таким же простым, как 'encode foo <> bar', где' foo' - ваше значение, тип которого является экземпляром 'ToJSON' и' bar' - это кодировка новой строки в любом кодирование JSON использует (возможно, UTF8?). –

+0

Хорошо, спасибо! Я буду искать правильный 'bar' –

Смежные вопросы