# Issue

I have this but I got an error:

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

# Solution

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:

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

Moreover, `length xs == 0`

should always be replaced with `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? 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:

```
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. 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.

Answered By - Stephan202 Answer Checked By - Cary Denson (PHPFixing Admin)

## 0 Comments:

## Post a Comment

Note: Only a member of this blog may post a comment.