简体   繁体   中英

How to convert a list of Strings to a list of tuples? (Haskell)

I have a list of Strings: students, their grade in a certain course, course name. I need to convert each String inside the list to a tuple since it holds both Strings and Integers.

["PHL 220 A 3 Ada Lovelace A", "PHL 220 A 3 Grace Hopper C","THE 105 A 3 Grace Hopper B+"]

to

[("PHL",220,"A",3,"Lovelace, Ada",4.0), ("THE",105,"A",3,"Hopper, Grace",3.33)]

I tried this, but it does not work.

listToTuples :: [[String]] -> [(String | Integer)]
    listToTuples = map listToTuples

I am very new to Haskell, so the syntax is very confusing.

There are quite a few errors in your provided attempt. Luckily, these errors are mostly syntactical, and you are approaching the problem correctly.

Let's go line by line:

listToTuples :: [[String]] -> [(String | Integer)]

This is almost correct, but:

  • You have specified the input type to be [[String]] — that is, a list of list of strings. However, your input is actually a list of strings — that is, [String] .
  • (String | Integer) is not correct Haskell syntax. Correct syntax is (String, Integer) . Additionally, your output type is actually a tuple of a string, an integer, a string, an integer, a string, and an integer, which translates to (String, Int, String, Int, String, Int) . (You can use Integer if you want, but it's not required; if you're interested, search for the difference between Int and Integer in Haskell.)

Putting these together, you get:

listToTuples :: [String] -> [(String, Int, String, Int, String, Int)]

That is, listToTuples , given a list of strings, will return a list of tuples. That sounds about right now!

Now, onto the next line:

    listToTuples = map listToTuples

You have two more mistakes here:

  • Don't indent it, If you indent this line, Haskell will interpret it as a continuation of the previous line. which this shouldn't be, (For more information on Haskell indentation, refer to https://en.wikibooks.org/wiki/Haskell/Indentation ).
  • You are defining listToTuples in terms of listToTuples . This cannot possibly do anything, When the compiler tries to run your code, it will run into an infinite loop, where in order to run listToTuples , it will try to run listToTuples on every element on the list, which in term means it has to run listToTuples on every element of those , meaning…

Luckily, you are doing one thing right: you are using map , As you have noticed, map is exactly the right tool for this problem. So a solution would look like the following:

listToTuples :: [String] -> [(String, Int, String, Int, String, Int)]
listToTuples = map _

But with _ replaced with a function converting a String to a (String, Int, String, Int, String, Int) . I will leave it to you to figure out what that function could be. (Hint: Use recursion to find all the bits between spaces, then use read to convert the strings to numbers.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM