如何在Haskell中组合过滤器和映射

时间:2019-04-14 11:15:24

标签: list haskell filter higher-order-functions map-function

我正在与haskell做一些练习。我的任务是从列表[0..10]中创建一个不带0的偶数平方的列表。

我已经使用Haskell中的列表理解来做到这一点(请看下面的代码块。)但是现在我的任务是使用功能mapfilter来实现它。

List comprehension in Haskell:
[x^2 | x <- [0..10], mod x 2==0, x/=0]


f = (\x -> (x^2))
p = (\x -> mod x 2 == 0 && x/=0)

map1 :: (a->b) -> [a] -> [b]
map1 f [] = []
map1 f (x:xs) = f x : map1 f xs

filter1 :: (a -> Bool) -> [a] -> [a]
filter1 p [] = []
filter1 p (x:xs)
 | p x = x:filter p xs
 | otherwise = filter1 p xs

我实现了mapfilter函数(我知道它是多余的,但它可以实现我的功能),并且我有一个平方函数。现在的问题是将mapfilter结合在一起,并且我还在error收到一条p = (\x -> mod x 3 == 0 && x/=0)消息。

我的错误消息是<interactive>:4:1: error: Variable not in scope : p :: Integer -> t

1 个答案:

答案 0 :(得分:1)

您已经在这里拥有了所需的一切。你写了

let res = [ x^2 | x <- [0..10], mod x 2==0, x/=0 ]

但这意味着你也可以写

let res = [ y^2 | y <- [ x | x <- [0..10] 
                           , (mod x 2==0 && x/=0) ] ]
==
let res = [ y^2 | y <- [ x | x <- [0..10], test x ] ]
   where
   test x = (mod x 2==0 && x/=0)
==
let res = [ y^2 | y <- baz [0..10] ]
   where
   baz xs = [ x | x <- xs, test x ]
   test x = (mod x 2==0 && x/=0)
==
let res = [ sqr y | y <- bar test [0..10] ]
   where
   sqr y = y^2
   bar p xs = [ x | x <- xs, p x ]
   test x = (mod x 2==0 && x/=0)
==
let res = quux ( bar test [0..10] )
   where
   quux ys = [ sqr y | y <- ys ]
   sqr y = y^2
   bar p xs = [ x | x <- xs, p x ]
   test x = (mod x 2==0 && x/=0)
==
let res = foo sqr ( bar test [0..10] )
   where
   foo f ys = [ f y | y <- ys ]
   sqr y = y^2
   bar p xs = [ x | x <- xs, p x ]
   test x = (mod x 2==0 && x/=0)

因此,我们现在拥有两个函数,foo f xs用于将函数f映射到列表xs上,bar p xs用于测试{{1}的每个元素}由谓词xs过滤掉所有未能通过该测试的(例如,所有p这样的x)。而且,事实证明,我们已经有了他们的定义!

我们需要从原始代码中提取它们的是抽象

p x == False
相关问题