2012-12-31 55 views
0
名单的

我有以下列表转换列表列出诠释

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) 
+3

'map(map read)' –

+0

@DanielFischer你能简单解释一下吗?这个怎么用? – Sibi

+1

查看'map'的一种方法是,它需要一个函数并将其提升到列表上(换句话说:'map ::(a - > b) - >([a] - > [b])')很显然,如果你想处理列表的列表,你必须使用一个已经在列表上工作的函数,并用'map'提取它,并且在这里,这个内部函数应该将'String'的列表转换为'Int'列表,换句话说,它应该将每一个String读入一个Int,所以它应该提升read以便在列表上工作,即map read。把它放在一起你'地图(地图阅读)'! – Jedai

回答

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类型签名(mapread(map read))[String]->[Int]而这不是read的工作方式。

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