【问题标题】:How to combine filter and mapping in Haskell如何在 Haskell 中结合过滤器和映射
【发布时间】:2019-09-04 13:52:33
【问题描述】:

我正在用 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 结合起来,我还在p = (\x -&gt; mod x 3 == 0 &amp;&amp; x/=0) 收到error 消息。

我的错误信息是&lt;interactive&gt;:4:1: error: Variable not in scope : p :: Integer -&gt; t

【问题讨论】:

  • 您收到什么错误信息? p 的定义在 GHCi 中对我来说很好。
  • 至于如何使用mapfilter 来获得与您的列表理解相同的结果-您尝试过哪种组合?你知道mapfilter 应用于哪些函数吗?
  • @RobinZigmond 我的错误信息是 :4:1: error: Variable not in scope : p :: Integer -> t
  • @RobinZigmond 我没有尝试太多,但这是我使用 Haskell 的第二天,我有点不知所措。
  • 我不建议尝试在交互式会话中完成所有这些操作。我认为这最终是您超出范围错误的原因。尝试将定义移动到文件中并使用:l将其加载到 GHCi 中

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


【解决方案1】:

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

let res = [ x^2 | x &lt;- [0..10], <b>mod x 2==0</b>, <b>x/=0</b> ]

但这意味着你也可以写

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 的每个元素并过滤掉所有未能通过该测试的人(即所有xs,例如p x == False)。而且,事实证明,我们已经有了他们的定义!

从原始代码中提取它们所需的只是抽象

let res = map sqr ( filter test [0..10] )
   where
   sqr y = y^2
   test x = (mod x 2==0 && x/=0)

【讨论】:

    猜你喜欢
    • 2015-11-20
    • 1970-01-01
    • 2011-08-09
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    • 2016-01-18
    • 1970-01-01
    相关资源
    最近更新 更多