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.