我正在和哈斯克尔做一些练习。我的任务是从列表[0..10]
创建一个偶数的平方列表,没有 0
我已经在 Haskell 中使用了列表理解(看看下面的代码块(,但现在我的任务是使用 map
和 filter
函数来实现这一点。
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
我实现了map
和filter
函数(我知道这是多余的,但它练习了我(,我有一个平方函数。现在的问题是将map
与filter
结合起来,我也在p = (x -> mod x 3 == 0 && x/=0)
收到一条error
消息。
我的错误消息<interactive>:4:1: error: Variable not in scope : p :: Integer -> t
你已经在这里拥有了你需要的一切。你写的
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 ys
用于将函数f
映射到列表ys
上,bar p xs
用于通过谓词p
测试xs
的每个元素并过滤掉所有无法通过该测试的元素(即所有x
,以便p x == False
(。而且,事实证明,我们已经有了他们的定义!
从原始代码中提取它们所需要的只是抽象。
let res = map sqr ( filter test [0..10] )
where
sqr y = y^2
test x = (mod x 2==0 && x/=0)