1

Here's what I could come up with but I don't think it's very efficient or safe:

import qualified Data.ByteString.Char8 as B8

convert2Int = read . B8.unpack

Is there a better way to do this? I found functions in libraries that do it for the Int type, but not for other types like Int32, Int64, Word64, etc.

donatello
  • 5,727
  • 6
  • 32
  • 56
  • 2
    Style advice: When composing functions, use spaces around the dot, as in `read . B8.unpack`. It looks quite confusing otherwise. – duplode Aug 28 '15 at 08:42
  • 1
    @duplode: a point could be made that it's quite confusing that `.` is used as the scope delimiter in the first place, but there's nothing we can do about this. (I would quite prefer `/`.) – leftaroundabout Aug 28 '15 at 09:35

2 Answers2

3

The most straightforward way is probably decode from Data.Binary:

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

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

There is also a decodeOrFail there, which produces an Either value if the decoding fails.

P.S.: How do I know that decode will work for the types you want? By reading the list of Binary instances.

donatello
  • 5,727
  • 6
  • 32
  • 56
duplode
  • 33,731
  • 7
  • 79
  • 150
0

An alternative way I found is to use the Attoparsec module:

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

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

Of course, this only works for strings without signs (unlike "-3" and "+5"). One may use "signed" instead of "decimal" in these cases.

donatello
  • 5,727
  • 6
  • 32
  • 56