Sibi
Sibi

Reputation: 48766

Convert List of List of String to List of List of Int

I have the following list

Prelude> let a = [["1676","17348","10"],["1677","18831","10"],["1677","18896","10"]]

I want to convert it to list of list of Int like this [[1676,17348,10],[1677,18831,10],[1677,18896,10]]

I have tried the following code, but it doesn't work:

f :: [[String]] -> [[Int]]
f [x] = map read (map read x)

Upvotes: 0

Views: 222

Answers (2)

Davorak
Davorak

Reputation: 7444

An alternative solution using lens library (Control.Lens) 3.7.1.2

import Control.Lens
f :: [[String]] -> [[Int]]
f = over (traverse.traverse) read

Now if instead we had:

Prelude> let a = [("1676","17348"),("1677","18831"),("1677","18896")]

f :: [[String]] -> [(Int, Int)]
f = over (traverse.both) read

Or for three tuples we would need a new function thrice by expanding from the definition of both.

Prelude> let a = [("1676","17348","10"),("1677","18831","10"),("1677","18896","10")]

import Control.Lens
import Control.Applicative

thrice f ~(a, a', a'') = (,,) <$> f a, <*> f a' <*> f a''

f :: [[String]] -> [(Int, Int, Int)]
f = over (traverse.thrice) read

Upvotes: 2

Manoj R
Manoj R

Reputation: 3247

Why map (map read) works.

The inner (map read) signature is [String] -> [Int]. So it will convert a list of String to list of Int. Now to apply it to list of list of String, you only have to raise it using map, hence map(map read) works. In this you are applying the function (map read) to each element on the list of [String] (or list of list of String, if that makes it better).
You can not have map read (map read), because the type signature of read is String -> Int. Your outer read type signature (mapread(map read)) is [String]->[Int] and that's not how read works.

Upvotes: 3

Related Questions