所以我创建了这个函数,给我列表中的“n”个第一个元素,“(b:bs);
1 module Sexta where
2
3 take6::Int->[a]->[a]
4 take6 n (b:bs) = if n<=0 then []
5 else [b] ++ (take6 (n-1) bs)
问题在于,当我尝试:take6 2 []
时,它会显示:
*** Exception: sexta.hs:(4,1)-(6,15): Non-exhaustive patterns in function take6
我不知道为什么,因为我亲手试试这个:
take6 2 []
= [] ++take6 1 []
= [] ++[]++take6 0 []
= [] ++[]++[]
= []
答案 0 :(得分:3)
在你的课程中你写道:
take6 n (b:bs) = ...
但是在这里你使用了一个模式(b:bs)
,它是列表的“cons”构造函数。 cons构造函数采用头b
和尾bs
。列表类型有两个构造函数:我们在这里讨论的“缺点”和空列表[]
。 Haskell抱怨它找不到第二个参数的空列表模式的子句。所以你的函数需要用一个形状来定义:
take6 n [] = ...
take6 n (b:bs) = ...
现在问题仍然是在这里做什么。无论我们在空列表的情况下采取什么,我们都不能再发出任何元素,所以你可能想要返回空列表,所以:
take6 _ [] = []
此外,你确实区分n
小于或等于零,在这种情况下结果是一个空列表:
take6 n (b:bs) | n <= 0 = []
但也有n > 0
的情况。在这种情况下,我们确实希望将b
添加到take6 (n-1) bs
。但是请注意,更有效的前置方法是再次使用“cons”构造函数:
| otherwise = b : take6 (n-1) bs
或完整:
take6 :: Int -> [a] -> [a]
take6 _ [] = []
take6 n (b:bs) | n <= 0 = []
| otherwise = b : take6 (n-1) bs
答案 1 :(得分:2)
模式b:bs
与空列表不匹配。您需要一个单独的案例来处理空列表。
答案 2 :(得分:2)
您在检查 n 之前对列表进行了解构,因此,即使它是0,您也要求列表为非空。您可以使用警卫来处理这种情况,但在列表太短的情况下,这不会有帮助。