2012-12-31 54 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