我正在对函数式语言进行一些自学(当前使用Haskell)。我遇到了一个基于Haskell的作业,该作业需要根据文件夹定义 map和过滤器。对于我的一生,我还没有完全理解如何去做。
例如,当我定义一个 map函数时:
map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = foldr (\x xs -> (f x):xs) [] xs
我不知道为什么总是忽略列表的第一个元素。意思是:
map' (*2) [1,2,3,4]
结果为[4,6,8]而不是[2,4,6,8]
同样,我的过滤器功能:
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs) = foldr (\x xs -> if p x then x:xs else xs ) [] xs
当运行为:
filter' even [2,3,4,5,6]
结果为[4,6]而不是[2,4,6]
为什么会这样呢?我应该如何定义这些函数以获得预期的结果?我假设我的Lambda表达式有问题...
我希望我可以发表评论,但是,我没有足够的业力。
其他答案都是好的答案,但我认为最大的困惑似乎是您使用x和xs造成的。
如果您改写为
map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = foldr (\y ys -> (f y):ys) [] xs
您会清楚地看到,x
甚至在右侧都没有提及,因此解决方案中不可能存在。
干杯
恰好。因此,应该明确指出,
map' f xs
而不是map' f (x:xs)
应该解决问题。顺便说一句GHC可以是有助于看到它时选择
-Wall
使用:Warning: Defined but not used: 'x'
(或者,对于原来的代码:This binding for 'x' shadows the existing binding
)现在,您应该在顶部有足够的业力和漂亮的徽章;)
谢谢,您是对的...我对x&xs的用法使我感到困惑!这确实使其更加清晰。
请更换
map' f (x:xs)
由map' f xs
丹·伯顿的建议