Reputation: 48766
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
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
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 (map
read
(map read))
is [String]->[Int]
and that's not how read
works.
Upvotes: 3