I wrote a function that takes a list as an input and outputs the sum of its elements, but I get the following error: "Pattern match(es) are non-exhaustive
In an equation for ‘addfunc’: Patterns not matched: []"
Here is my code:
addfunc :: [Int] -> Int
addfunc(x:xs) = x + addfunc xs
When pattern matching, you have to list out all possible cases, so that your program knows what to do for every possible input. Here, the possible input is all lists of integers, which also includes an empty list (a list of zero integers). Your function knows what to do when the input has a first element and other elements; but if it should receive an empty list (which cannot be decomposed into the first element and the other elements), it would not know what to do.
To correct it, simply provide the matching rules for the missing case(s), e.g.
addfunc [] = 0
Related
I wrote the following code to find the last element of a list in haskell:
myLast (x:xs) = do
ret <- if xs == [] then x else (myLast xs)
return ret
The idea is to traverse the list until we are at an element which has the empty list as its next element. When we find it we set ret to that element.
It makes sense for me but when I run the code inside the interactive shell I get the following error:
<interactive>:1:1: error:
• No instance for (Num (m0 b0)) arising from a use of ‘it’
• In a stmt of an interactive GHCi command: print it
edit 1
The reason I used do was because I saw that pattern being used somewhere to also traverse a list, so I thought I could do the same here. I'am avoiding libraries for now to get comfortable with the language.
I wrote the function avoiding the do keyword and now it works:
myLast(x:xs) = if xs == [] then x else (myLast xs)
There's now just an issue with the empty list case. How to approach this in haskell?
let's start with the signature of your function
myLast :: [a] -> a
now, for an empty list input, what can be expected as the output? How you can make up an instance of an arbitrary type a?
Alternatively, you can defer the handling of missing last element to the callers of your function.
myLast :: [a] -> Maybe a
You want
myLast (x:xs) =
to be equal to
if xs == [] then x else (myLast xs)
Great, xs == [], so let's just put it back in:
myLast (x:[]) = x
but what about the else part? Well, let's add another equation for that,
myLast (_:xs) = myLast xs
and we're golden.
What if we call it with an empty list [] though? No definition case will match, and we will get some kind of a run-time error. Well, same thing happens with the built-in function last too, so we're no better and no worse than Haskell itself here.
What is that match that I mentioned, you ask? That's how Haskell functions get invoked. Each function definition can have several clauses, starting with the function's name, and containing a pattern for each expected argument.
In a left hand side of an equation,
(x:[]) is a pattern, matching any singleton list. It can also be written [x]. x will refer to the list's only element, if used in the right-hand side of the equation.
[] is a pattern, matching any empty list.
(x:xs) is a pattern, matching any non-empty list. x will refer to the list's head (i.e. first) element, if used in the right-hand side of the equation; and xs will refer to the rest of the elements in a list (which are also, a list -- also known as its tail).
But wait, you ask. Wouldn't both clauses match for a singleton list, the first for the pattern [x] and the second for (_:xs) with xs matched up with an empty list, []?
Why yes, they both would match indeed; (x:[]) and (_:xs) are not mutually exclusive.
But that's OK, because in Haskell, if the first clause has matched, that's it -- that is the clause that gets executed, and no other attempts at any additional pattern matching and clause selection are made.
That would be Prolog, and that's quite another language.
I have this code:
[a,b,[]]=[First,Second,Third|Fourth].
and it gives me the following output:
First = a, Second = b, Third = Fourth, Fourth = [].
I'd like to know how Third got assigned to Fourth.
The pipe character is very similar to the "consing dot" in Lisp. The variable after the pipe takes the entire remainder of the corresponding list.
So, here we expect Third to bind to the explicitly given empty list in the data. But there is nothing after that and so Fourth also binds empty.
Third being bound to Fourth is just an indirect way of Third being bound to empty.
See my answer here: https://stackoverflow.com/a/7559044/467473 for details on how Prolog lists are implemented.
Basically, a prolog list is a simple data structure. The empty list is denoted by the atom []. A non-empty list is the structure ./2. The left argument in this structure is the head of the list; the right argument is the tail of the list, which is another list (either the empty list [] or a non-empty list (./2).
The friendly list notation is just syntactic sugar on top of this. The expression [H|T] is exactly the same as the expression .(H,T). The expression [a,b|T] is exactly the same as .(a,.(b,T)). And the expression [a,b,c] is exactly the same as .(a,.(b,.(c,[]))).
I just started working with Haskell and stumbled on a problem.
According to Haskell, I have a pattern match failure, but I fail to see how.
This is the code I try to execute:
statistics :: [Int] -> (Int, Int, Int)
statistics [gradelist] = ( amountParticipants, average, amountInsufficient)
where
amountParticipants= length [gradelist]
average= sum[gradelist] `div` amountParticipants
amountInsufficient= length [number| number<- [gradelist], number<6]
I call 'statistics' with:
statistics[4,6,4,6]
this causes a pattern match failure, while I expect to see : (4, 5, 2)
statistics[6]
gives the answer : ( 1, 6, 0 ) (which is correct).
Can someone tell me why my first call causes this pattern match? Because I'm pretty sure I give a list as an argument
If you write statistics [gradelist] = ... you are pattern matching against a singleton list containing a sole element referred to as gradelist. Hence, your function is only defined for lists of length exactly 1 (such as [6]); it is undefined for the empty list ([]) or lists with two or more elements (such as [4,6,4,6]).
A correct version of your function would read
statistics :: [Int] -> (Int, Int, Int)
statistics gradelist = (amountParticipants, average, amountInsufficient)
where
amountParticipants = length gradelist
average = sum gradelist `div` amountParticipants
amountInsufficient = length [number| number <- gradelist, number < 6]
As #thoferon remarked, you will also need to make special arrangements for the case in which gradelist is empty, in order to avoid dividing by zero when computing average.
Just replace your [gradelist]'s by gradelist as said before. Also, you might want to match against the empty list with [], in order to avoid dividing by zero in average, like :
statistics [] = (0,0,0)
The list syntax [ ] in a pattern deconstructs a list. The pattern [gradelist] matches a list holding exactly one value, and it names the value in the list gradelist. You get a pattern match failure if you try to call the function with a list holding four values.
To match a value without deconstructing it, use a variable as the pattern.
I've been trying to solve this pair tuples problem where the input is a list of tuples and the output is a tuple of lists where the first element of each tuple is grouped together and similarly with the second (i.e. [(1,2),(3,4),(5,6)] --> ([1,3,5],[2,4,6])).
I've thought of this code but it gives me an error:
fun convert L = foldl (fn ((x,y),(u,v)) => ((u#x),(v#y)) ([],[]) L;
Any suggestions for a fix?
Concatenation (#) takes two lists, but x and y are values, so you need to wrap them with [] to make a single-element list:
fun convert l=foldl (fn((x,y),(u,v))=>(u#[x],v#[y])) (nil,nil) l
You can use cons instead of concatenation, though the lists inside the returned tuple are reversed:
fun convert l=foldl (fn((x,y),(u,v))=>(x::u,y::v)) (nil,nil) l
# concatenates lists (and x and y are not lists).
Try (u#[x],v#[y]).
Note, however, that appending is a linear-time operation, while prepending (i.e. x::u) is constant. As Alex pointed out, this will build your lists in reverse, but you can resolve this by processing your input in reverse as well - i.e., by using foldr instead of foldl.
// But pattern matching also makes it easy.
def penultimateRecursive[A](ls: List[A]): A = ls match {
case h :: _ :: Nil => h
case _ :: tail => penultimateRecursive(tail)
case _ => throw new NoSuchElementException
}
Can someone comment what this is doing line by line?
Is the [A] a generic like in c# we would do ?
h doesn't seem to be defined?
I think the major part of the algo is the recursive call:
case _ :: tail => penultimateRecursive(tail)
There doesnt' seem to be a check for 2 items in the list, and then taking the 1st item to get the 2nd last, confused!
The keys to understanding the pattern match are to realize that x :: y will only match a list with a single item x followed by the rest of the list y (which could be just Nil, or could be many elements), and that _ means "there needs to be something here, but we won't bother naming it". (And that the matches occur in order, and that lists end with Nil.)
You're correct that [A] is a generic type.
So, the first line:
case h :: _ :: Nil => h
says, if our list looks like (conceptually) Node(h) -> Node(whatever) -> Nil, then we return h. This is exactly a two-element list with the first item selected. Note that Nil does not match any arbitrary tail of the list; it matches only the end-of-list item Nil. This is because of a rule that Scala uses to distinguish the two: lower case variables are treated as wildcards that are to have the appropriate value filled in, while upper case variables are treated as constants to match. (If you must match a lower-case name, you can if surround it by backticks.)
Okay, now suppose it's not a two-element list. Then if it's not empty, it will match
case _ :: tail => penultimateRecursive(tail)
so if we haven't got a two-element list, we throw away the first item and try again. Finally, if we somehow never ended up with a two-element list, we get to
case _ => throw new NoSuchElementException
and we're done. (This could also be case Nil, actually, since this is the only possibility that doesn't match the other two entries.)
A is a type variable, meaning the function is defined generically for any type A.
h is bound by the pattern matching: the first case states, if there are exactly two elements, then call the first h and return it.
There doesnt' seem to be a check for 2 items in the list
There is: h :: _ :: Nil means "an element h, followed by any element, followed by no more elements." Nil isn't an element, it's the end of the list.
and then taking the 1st item to get the 2nd last
Taking the first of a two-element list means taking the penultimate. If the list has fewer or more elements than two, the other two cases apply.
larsmans and Rex have covered your questions, but see Chapter 9 for more details on '::' http://www.scala-lang.org/docu/files/ScalaByExample.pdf
The first line means that any list element h will be returned if h is followed by another one and a Nil pointer (at the end of the list). The actual element following to h is not important, that's why you use _ to specify that there is an element but you don't care about its value.
If the first case does not match, the second case will invoke recursion if the list has a head element and a tail of at least one element.
Lastly you bail out on lists consisting only a single element. Once again, you don't have to care about the actual value of the elements value.