matching the output of a standard function to my function definition (non-exhaustive pattern problem)

Dear all I am sure this is a very beginner problem, but I am not sure how to solve it: I have a myFunct function: myFunct :: Int -> [a] -> a defined as: myFunct _ [] = error "empty list provided as arg" myFunct a [b] | length [x|x<-[b],fid x == a] == 0 = error "no match" | otherwise = head [x|x<-[b],fid x == a] Which works fine (may not be elegant, but works). Now, I am chaining it in a larger function, where at some stage I use a graph object from Data.Graph and check for its edges, resulting in [(Int,Int)] trying to run this fails: myFunct (fst (head (edges graph))) myList *** Exception: FunctStruct.hs:(136,1)-(138,48): Non-exhaustive patterns in function myFunct contrived example, but myList is a list of [a]). The problem arrises from the definition of the type of Edge as (Vertex,Vertex), but type Vertex = Int (http://hackage.haskell.org/packages/archive/containers/0.2.0.1/doc/html/Data...), so that should be ok, or am I making a mistake somewhere and I should go from vertex to Integer explicitly? Thanks a lot! Martin

On Monday 27 September 2010 17:41:24, Martin Tomko wrote:
Dear all
I am sure this is a very beginner problem, but I am not sure how to solve it: I have a myFunct function: myFunct :: Int -> [a] -> a
defined as: myFunct _ [] = error "empty list provided as arg" myFunct a [b] | length [x|x<-[b],fid x == a] == 0 = error "no match" | otherwise = head [x|x<-[b],fid x == a]
The pattern `[b]' matches only lists of length 1. [b] is syntactic sugar for (b : []) So when you pass a longer list to the function, no pattern matches. Presumably you wanted the second equation to treat all nonempty lists, n which case you simply have to replace all three occurrences of `[b]' with a generic variable, e.g. b. Since you test for empty lists first, no empty list ever reaches that equation. Also, don't use length list == 0 to check for empty lists, if list is long, that needs a long time (and possibly a lot of space). To check for empty lists, use null. Or pattern match. That would also improve the style in the second equation: myFunct _ [] = error ".." myFunct a xs = case [x | x <- xs, fid x == a] of [] -> error "no match" (y:_) -> y Cheers, Daniel

Dear Daniel that worked perfectly, thanks for the suggestion! One more question: how do you use null to check for empty lists? something like [] == null did not work ... just chekcing, I got my orignal code to work, thanks again! Martin On 9/27/2010 5:56 PM, Daniel Fischer wrote:
On Monday 27 September 2010 17:41:24, Martin Tomko wrote:
Dear all
I am sure this is a very beginner problem, but I am not sure how to solve it: I have a myFunct function: myFunct :: Int -> [a] -> a
defined as: myFunct _ [] = error "empty list provided as arg" myFunct a [b] | length [x|x<-[b],fid x == a] == 0 = error "no match" | otherwise = head [x|x<-[b],fid x == a]
The pattern `[b]' matches only lists of length 1. [b] is syntactic sugar for (b : [])
So when you pass a longer list to the function, no pattern matches.
Presumably you wanted the second equation to treat all nonempty lists, n which case you simply have to replace all three occurrences of `[b]' with a generic variable, e.g. b.
Since you test for empty lists first, no empty list ever reaches that equation.
Also, don't use length list == 0 to check for empty lists, if list is long, that needs a long time (and possibly a lot of space).
To check for empty lists, use null.
Or pattern match. That would also improve the style in the second equation:
myFunct _ [] = error ".." myFunct a xs = case [x | x<- xs, fid x == a] of [] -> error "no match" (y:_) -> y
Cheers, Daniel

On Mon, Sep 27, 2010 at 06:15:22PM +0200, Martin Tomko wrote:
Dear Daniel that worked perfectly, thanks for the suggestion!
One more question: how do you use null to check for empty lists? something like [] == null did not work ... just chekcing, I got my orignal code to work, thanks again! Martin
When in doubt, consult the types! null :: [a] -> Bool That is, null is a function for testing lists to see whether they are empty. So rather than 'list == null' you write 'null list'. -Brent

On Mon, Sep 27, 2010 at 05:41:24PM +0200, Martin Tomko wrote:
Dear all
I am sure this is a very beginner problem, but I am not sure how to solve it: I have a myFunct function: myFunct :: Int -> [a] -> a
defined as: myFunct _ [] = error "empty list provided as arg" myFunct a [b] | length [x|x<-[b],fid x == a] == 0 = error "no match" | otherwise = head [x|x<-[b],fid x == a]
May I also suggest that instead of implementing this yourself, you could just use myFunct a b = find ((==a) . fid) b 'find' is from Data.List and returns the first thing in the list satisfying the given predicate, or Nothing if there is no such element. -Brent
participants (3)
-
Brent Yorgey
-
Daniel Fischer
-
Martin Tomko