Converting Data.Text to Int in Haskell

10,472

Solution 1

Looking at the text package, I see a module called Data.Text.Read. It seems to work:

λ> decimal (T.pack "99 bottles")
Right (99," bottles")
λ> decimal (T.pack "a digit")
Left "input does not start with a digit"

Solution 2

In other words, you want a parser that can consume Text. There are many parsers on hackage that can consume Text, I suggest you try attoparsec.

import Data.Attoparsec.Text
parseInt = parseOnly (signed decimal)
Share:
10,472
Ralph
Author by

Ralph

Physician, retired. Retired software engineer/developer (Master of Science in Computer Science). I currently program mostly in Go. I am particularly interested in functional programming. In past lives, I programmed in Java, Scala, Basic, Fortran, Pascal, Forth, C (extensively, at Bell Labs), C++, Groovy, and various assembly languages. Started programming in assembly language in 1976. I started a martial arts school in 1986 (Shojin Cuong Nhu in New Jersey) and currently teach at the Tallest Tree Dojo in Gainesville, Florida. I like to cook. I am an atheist. Email: user: grk, host: usa.net

Updated on July 29, 2022

Comments

  • Ralph
    Ralph almost 2 years

    In another question, one of the comments says, "[Data.]Text is becoming the de-facto textual implementation. String is still around for legacy reasons and for simple things, but for serious textual manipulation you should be using Text."

    What is the easiest way to convert a Data.Text to an Int? read will not work because the read function always takes a String.

    The best that I can come up with is:

    let fortyTwo = Data.Text.pack "42"
    read $ Data.Text.unpack fortyTwo :: Int
    

    Is there a better way?

  • Ralph
    Ralph over 11 years
    I'm not sure that will be shorter (or better), since I will still have to deal with the Either. That might be a reasonable replacement for reads.
  • shachaf
    shachaf over 11 years
    Well, you have to deal with that anyway, for most uses of read. read will crash your program if it sees a malformed string, which is pretty bad (it would probably be better if its type was Read a => a -> Maybe String). If you're sure you want to crash your program, you can always define foo f = fst . either error id . f, and then use foo decimal instead of decimal.
  • Ralph
    Ralph over 11 years
    In my case, I know the string is a number; it comes from a regular expression match ("\d{2}").
  • ДМИТРИЙ МАЛИКОВ
    ДМИТРИЙ МАЛИКОВ over 11 years
    What is at mean «know the string is a number»? If you know that something is a number, that it is a number. These types are not equal, that why not every String could be converted to Int. Maybe something like either (const 0) fst will be useful, which is kinda fromMaybe 0.
  • shachaf
    shachaf over 11 years
    Then feel free to do what I said. Crashing your program shouldn't be the default. :-) An alternative might be to combine the regular expression match and the reading into one function that returns Either/Maybe. It depends on what your code is like.
  • Ralph
    Ralph over 11 years
    Please don't misunderstand. I like your answer.