Haskell:List Comprehensions和高阶函数

时间:2014-04-22 00:00:08

标签: haskell higher-order-functions

我试图改变以下列表理解:

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元组列表。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:4)

  

两种版本的f&#39;给出相同(正确)的输出,但在元组列表中使用map时,我不明白为什么(+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