list - 函数 take6 错误中的非详尽模式?

标签 list haskell take

所以我创建了这个函数,给我列表中的“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 []
   = [] ++[]++[]
   = []

最佳答案

在您的程序中编写:

take6 n (b:bs) = ...

但是在这里你使用了一个模式(b:bs),它是列表的“cons”构造函数。 cons 构造函数采用头部 b 和尾部 bs。然而,列表类型有两个构造函数:我们已经在这里讨论过的“cons”和空列表[]。 Haskell 提示它找不到第二个参数的空列表模式的子句。所以你的函数需要用一个形状来定义:

take6 n [] = ...
take6 n (b:bs) = ...

现在的问题仍然是在这里做什么。无论我们在空列表的情况下采取什么措施,我们都不能再发出任何元素,因此您可能想返回空列表,因此:

take6 _ [] = []

此外,您确实区分了 n 小于或等于零,在这种情况下结果是一个空列表:

take6 n (b:bs) | n <= 0 = []

但也有n > 0的情况。在这种情况下,我们确实希望在 take6 (n-1) bs 前面添加 b。但请注意,更有效的前置方式是再次使用“cons”构造函数:

               | otherwise = b : take6 (n-1) bs

或完整:

take6 :: Int -> [a] -> [a]
take6 _ [] = []
take6 n (b:bs) | n <= 0 = []
               | otherwise = b : take6 (n-1) bs

关于list - 函数 take6 错误中的非详尽模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46635565/

相关文章:

python - Python 的列表方法 append 和 extend 有什么区别?

Haskell 在包含底部类型的 Foldables 上折叠交换、关联函数

haskell - Functor 实例 for (newtype Mu f = InF {outF::f (Mu f)})

haskell - 为快速检查生成无偏图的任意实例

sql - 在 SQL 语句中使用 LIMIT 时性能提高了多少?

linq - 我对 LINQ 表达式有一些问题,OrderBy()、Skip()、Take() 工作不正确

java - 在 Java 中过滤列表

c# - 列表、数组和 IEnumerable 协方差

list - 获取列表中的第 N 个元素作为列表而不是 LISP 中的数字?

java阻塞队列消费者阻塞在完整队列上