简体   繁体   English

您如何检测列表中Haskell中是否恰好有3个项目?

[英]How do you detect if a list has exactly 3 items in Haskell?

I have this but I got an error: 我有这个,但是我得到一个错误:

-- test if a list contains exactly three characters
test :: [Char] -> Bool
test xs   | [_ , _ , _] = True
          | otherwise = False

Pattern matching happens on the left side of the vertical bar. 模式匹配发生在垂直条的左侧 Thus: 从而:

test :: [Char] -> Bool
test [_, _, _] = True
test _         = False

As Norman Ramsey rightly notes below, the following code is not a robust alternative solution (because it is very inefficient when applied to (long) finite lists and does not halt on infinite lists) and should thus not be used: 正如Norman Ramsey在下面正确指出的那样,以下代码不是一个健壮的替代解决方案(因为将其应用于(长)有限列表时效率非常低,并且不会在无限列表上停止),因此不应使用:

test :: [Char] -> Bool
test xs = length xs == 3

Moreover, length xs == 0 should always be replaced with null xs . 此外, length xs == 0应该始终替换为null xs

Edit: the question which naturally arises is: how do we generalize this? 编辑:自然而然出现的问题是: 我们如何对此进行概括? What if we want to test whether a list has exactly n elements? 如果我们要测试列表是否恰好具有n个元素怎么办? What if the input may be infinite? 如果输入可能是无限的怎么办? Here's a solution where the cost is either n or the length of the list, whichever is smaller—and that's as efficient a solution, asymptotically, as we can possibly hope for: 这是一个成本为n或列表长度(以较小者为准)的解决方案,这是渐近有效的解决方案,正如我们可能希望的那样:

hasLength :: Int -> [a] -> Bool
hasLength n []     = n == 0
hasLength 0 (x:xs) = False
hasLength n (x:xs) = hasLength (n-1) xs

Usage: 用法:

*Main> hasLength 3 [1..2]
False
*Main> hasLength 3 [1..3]
True
*Main> hasLength 3 [1..4]
False
*Main> hasLength 3 [1..] 
False

It is unsafe to call this function with a negative length; 以负长度调用此函数是不安全的 if the list is infinite, the function won't terminate, and if the list is finite, it will return False with cost proportional to the length of the list. 如果列表是无限的,该函数将不会终止;如果列表是有限的,则它将返回False ,其成本与列表的长度成比例。 An easy fix would be to check in advance (on the first call only) that n is nonnegative, but this fix would ugly up the code. 一个简单的解决方法是预先检查(仅在第一次调用时) n是否为负数,但是此解决方法会使代码难看。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM