将String列表的列表转换为Int列表的列表

时间:2012-12-31 08:33:43

标签: haskell

我有以下列表

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

我想将它转换为Int列表的列表,如[[1676,17348,10],[1677,18831,10],[1677,18896,10]]

我尝试了以下代码,但它不起作用:

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

2 个答案:

答案 0 :(得分:3)

为什么map (map read)有效。

内部(map read)签名是[String] -> [Int]。因此,它会将String的列表转换为Int列表。现在将其应用于String列表列表,您只需使用map进行提升,因此map(map read)有效。在此,您将函数(map read)应用于[String]列表中的每个元素(或String列表列表,如果这样做更好)。
您不能拥有map read (map read),因为read的类型签名是String -> Int。您的外read类型签名(map read (map read))[String]->[Int],而read的工作方式不是{{1}}。

答案 1 :(得分:2)

使用lens库(Control.Lens)3.7.1.2

的替代解决方案
import Control.Lens
f :: [[String]] -> [[Int]]
f = over (traverse.traverse) read

现在,如果我们有了:

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

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

或者对于三个元组,我们需要通过从两者的定义扩展来获得新函数三次。

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