Electric Coffee
Electric Coffee

Reputation: 12104

How do I parse a string into a record in Haskell?

In C, reading the data in a string and putting its data into a struct is fairly straight forward, you just use something along the lines of sscanf to parse your data:

struct ingredient_dose ingr;

char *current_amount = "5 tsp sugar";

sscanf(current_amount, "%d %s %s", &ingr.amount, ingr.unit, ingr.ingredient);

Which would fill the struct/record with the given data.

How would I do something similar in Haskell? I realise you can't mutate anything once it's made, so the procedure will obviously be a bit different from the C example, but I can't seem to find a decent guide that doesn't include parsing JSON.

Upvotes: 1

Views: 1174

Answers (1)

MathematicalOrchid
MathematicalOrchid

Reputation: 62818

Haskell doesn't have any built-in function which does exactly what scanf does.

However, if your stuff is space-delimited, you could easily use words to split the string into chunks, and the read function to convert each substring into an Int or whatever.

parse :: String -> (Int, String, String)
parse txt =
  let [txt1, txt2, txt2] = words txt
  in  (read txt1, txt2, txt3)

What Haskell does have an abundance of is "real" parser construction libraries, for parsing complex stuff like... well... JSON. (Or indeed any other computer language.) So if your input is more complicated than this, learning a parser library is typically the way to go.


Edit: If you have something like

data IngredientDose = IngredientDose {amount :: Double, unit, ingredient :: String}

then you can do

parse :: String -> IngredientDose
parse txt =
  let [txt1, txt2, txt2] = words txt
  in  IngredientDose {amount = read txt1, unit = txt2, ingredient = txt3}

Upvotes: 4

Related Questions