2014-04-22 150 views
2

我試着變換以下列表理解:使用哈斯克爾:列表中的理解與高階函數

f xs = [ x+8 | (x,_) <- xs ] 

高階函數。

我的第一個解決方案是:

f' xs = map (\(x,_) -> x+8) xs 

我嘗試了各種其他辦法後,我發現以下也適用:

f' xs = map((+8).fst) xs 

f'兩個版本提供相同的(正確)的輸出,但我不明白爲什麼(+8).fst等於\(x,_) -> x+8在元組列表上使用map

回答

7

fst定義是

fst :: (a, b) -> a 
fst (a, _) = a 

和定義的(.)

(.) :: (b -> c) -> (a -> b) -> a -> c 
(f . g) = \x -> f (g x) 

如果我們用這些定義來擴展你的函數,我們得到

f' xs = map ((+8) . fst) xs 
f' xs = map (\x -> (+8) (fst x)) xs   -- definition of (.) 
f' xs = map (\x -> (+8) ((\(a, _) -> a) x)) -- definition of fst 
f' xs = map (\(a, _) -> (+8) a)    -- we can move the pattern matching 
f' xs = map (\(a, _) -> a + 8)    -- expand section 
+0

愛直接的答案,等式推理ftw。 +1 – luqui

4

的F兩個版本」給予同樣的(正確)的輸出,但我不明白爲什麼(+8).fst元組的列表上使用地圖時等於(x,_) -> x+8

類型的fst是:

fst :: (a, b) -> a 

和它做什麼是它需要一對的第一個元素(兩個元件中的一個元組)。

類型的(+8)是:

(+8) :: Num a => a -> a 

,什麼它是它需要輸入一個Num,適用+ 8它並返回結果。現在

,的(+8) . fst類型是:

((+8).fst) :: Num c => (c, b) -> c 

這是fst(+8)和組合物。具體來說,它是作爲輸入一對的函數,提取第一個元素並將其添加到8

這可以看出一個例子很容易地看到:

((+8).fst) (3, 'a') 
-- 11 

同樣的事情發生與\ (x, _) -> x + 8。你把一對作爲輸入(在lambda),圖案匹配的第一個參數x,通過8遞增,並返回它:

(\ (x, _) -> x + 8) (3, 'a') 
-- 11 
+0

你的解釋說得很清楚,不幸的是我不能接受兩個答案。 – Josh