1

我的任务是重新实现这个功能

divn :: Integer -> [Integer] -> [Integer]
divn _ [] = []
divn n (x:xs) | mod x n == 0 = x : divn n xs
              | otherwise = divn n xs

使用“文件夹”。我做了什么:

divn' _ [] = []
divn' n (x:xs) = foldr (\x -> if (mod x n == 0) (x:) ([]++)) [] xs

我以为这会奏效。实际上它甚至没有编译,而是说:“输入时解析错误“)”。

由于我没有发现任何错误,我决定重新编写,好像现在它正在工作......

if' True x _ = x
if' False _ x = x

divn' _ [] = []
divn' n (x:xs) = foldr (\x -> if' (mod x n == 0) (x:) ([]++)) [] xs

有谁知道错误在哪里?

谢谢!

4

2 回答 2

4

if在 Haskell 中需要 athen和 an ,else

(\x -> if (mod x n == 0) (x:) ([]++))

应该

(\x -> if (mod x n == 0) then (x:) else id)
于 2012-07-14T13:24:57.743 回答
3

除了 Daniel Fischer 所说的,您不需要任何单独的案例:没有递归,空列表案例将由 foldr 处理。在您的代码中,第一个x总是忽略!正确的是

divn' n xs = foldr (\x -> if x`mod`n == 0 then (x:) else id) [] xs

或者,通过 η 归约,

divn' n = foldr (\x -> if x`mod`n == 0 then (x:) else id) []

当然,简单地做会更惯用

divn'' n = filter ((==0) . (`mod`n))
于 2012-07-14T13:55:40.790 回答