所以,我的问题是,我必须编写一个程序来过滤列表中的所有3 * x(3,6,9 ...)元素。我的程序看起来像:
length' :: [a] -> Int
length' = foldr (\_ -> (+1)) 0
help_ :: [a] -> [a] -> [a]
help_ (x:xs) [] = help_ (xs) [x]
help_ [] (x) = (x)
help_ (x:xs) (y)
|((length' [xs]) ==0) = (y)
|((length' [y]) `mod` 2 ==0) = help_ (xs) (y)
|otherwise = help_ (xs) (y++[x])
noThirds :: [a] -> [a]
noThirds [x] = help_ [x] []
编译器接受此但在我输入时会出现错误“函数noThirds中的非穷举模式” “noThirds [1,2,3,4,5,6,7,8]” 。我想这是因为我错过了各种各样的“帮助......”但是我没有得到它。我很感激每一个帮助! 不允许使用Btw预定义列表和算术函数。
答案 0 :(得分:2)
jozefg已经回答了你的问题。我还要指出更多的事情。
小心!表达式
((length' [xs]) ==0)
((length' [y]) `mod` 2 ==0)
评估为
(1 ==0)
(1 `mod` 2 ==0)
所以他们都是假的。你想要
((length' xs) ==0)
((length' y) `mod` 2 ==0)
此外,在这些功能中,计算长度通常会导致性能低下,并且被认为是不好的风格。考虑以这种方式预处理您的列表
addPosition :: [a] -> [(Int,a)]
addPosition xs = go 0 xs
where go n [] = ...
go n (y:ys) = ...
-- Example: addPosition [33,66,20] ===> [(0,33),(1,66),(2,20)]
-- This is equivalent to (zip [0..]) but we can not use list functions.
然后,添加一些后处理来过滤想要的元素:现在这更容易,因为每个元素都被其位置标记。
答案 1 :(得分:1)
这是因为noThirds
只有一个模式,[x]
只与单个元素列表匹配。
[x]
完全等同于(x : [])
。我认为你的意思是
noThirds :: [a] -> [a]
noThirda xs = help_ xs []
答案 2 :(得分:0)
列表的结构是:
使用列表的结构来定义结果(使用保护表达式):
noThirds :: [Int] -> [Int]
noThirds [] = []
noThirds (x:xs)
| x `mod` 3 == 0 = rest
| otherwise = x : rest
where
rest = noThirds xs
该功能现在过滤掉所有可被3整除的元素。
你可能希望过滤掉一个可被3整除的索引的所有元素。为此,引入一个辅助函数,它传递你当前所在的索引并改为使用索引上的guard:
noThirds :: [Int] -> [Int]
noThirds xs = noThirds' xs 1
noThirds' :: [Int] -> Int -> [Int]
noThirds' [] _ = []
noThirds' (x:xs) i
| i `mod` 3 == 0 = rest
| otherwise = x : rest
where
rest = noThirds' xs (succ i)
现在您不需要计算列表的长度。
关于H-99的解决方案16的更多答案:九十九个Haskell问题: http://www.haskell.org/haskellwiki/99_questions/Solutions/16