我有以下列表
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)
答案 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