2015-08-28 4 views
1

Вот что я мог придумать, но я не думаю, что это очень эффективно и безопасно:Generic и эффективный способ для разбора различных видов чисел из байтовых строк в Haskell

import qualified Data.ByteString.Char8 as B8 

convert2Int = read . B8.unpack 

Есть ли лучший способ сделать это? Я нашел функции в библиотеках, которые делают это для Int типа, но не для других типов, как Int32, Int64, Word64 и т.д.

+2

Рекомендации по стилю: при составлении функций используйте пробелы вокруг точки, как в 'read. B8.unpack'. Это выглядит довольно запутанным. – duplode

+1

@duplode: можно указать, что это довольно запутанно, что '.' в первую очередь используется как ограничитель объема, но мы ничего не можем с этим поделать. (Я бы предпочел '/'.) – leftaroundabout

ответ

3

Самый простой способ, вероятно, decode от Data.Binary:

import qualified Data.ByteString.Lazy as BL 
import Data.Binary (decode) 

convertToIntegral :: (Binary a, Integral a) => BL.ByteString -> a 
convertToIntegral = decode 

Eсть также есть decodeOrFail, который генерирует значение Either, если декодирование завершается с ошибкой.

P.S .: Откуда я знаю, что decode будет работать для тех типов, которые вам нужны? Читая the list of Binary instances.

+0

Спасибо! Я думаю, вы имели в виду 'a' вместо' Int64'. Я подал заявку на редактирование. – donatello

+0

@ donatello Действительно. Спасибо, что поймали это! – duplode

0

Альтернативный способ я нашел, чтобы использовать Attoparsec module:

import Data.Attoparsec.ByteString.Char8 
import qualified Data.ByteString as B 

convertToIntegral :: (Integral a) => B.ByteString -> Either String a 
convertToIntegral = parseOnly decimal 

Конечно, это работает только для строк без признаков (в отличие от «-3» и «+5»). В этих случаях можно использовать «подписанный» вместо «десятичный».