This question already has answers here:
Better exception for non-exhaustive patterns in case
(2 answers)
Closed 1 year ago.
I'm learning Haskell and working on a Hamming distance exercise.
module Hamming (distance) where
distance :: String -> String -> Maybe Int
distance (x:xs) (y:ys)
| lengthX /= lengthY = Nothing
| lengthX == 0 = Just 0
| otherwise = Just (headDistance + tailDistance)
where
lengthX = length (x:xs)
lengthY = length (y:ys)
headDistance = if x /= y then 1 else 0
(Just tailDistance) = distance xs ys
When I run it, distance "" "" gives the error:
haskell/hamming » stack test
hamming> test (suite: test)
distance
empty strands FAILED [1]
Failures:
src/Hamming.hs:4:1:
1) distance empty strands
uncaught exception: PatternMatchFail
src/Hamming.hs:(4,1)-(12,40): Non-exhaustive patterns in function distance
To rerun use: --match "/distance/empty strands/"
Randomized with seed 892503112
Finished in 0.0003 seconds
1 example, 1 failure
hamming> Test suite test failed
Test suite failure for package hamming-2.3.0.10
test: exited with: ExitFailure 1
Logs printed to console
I used guards instead of pattern matching for the main stuff, so it looks like it's that last where statement is the only place where pattern matching occurs, and must be what is causing the error. I see that it doesn't match against the Nothing output.
However, I don't see how it could ever produce Nothing, since things get evaluated lazily, I thought. In the case where the original strings are of different lengths, Nothing will be returned immediately and distance will never be called recursively, right?
This error isn't anything to do with your guards - it's much more basic than that.
You have:
distance :: String -> String -> Maybe Int
distance (x:xs) (y:ys)
- - more code
but no other cases. So you do indeed have non-exhaustive patterns, because the only case you cover is when the first argument matches (x:xs), and the second (y:ys) so it will crash as soon as either argument is empty - let alone both, as you are calling it here.
I know 2 of these statements are true, but I dont know which
Let e be an expression of type [Int]
there exists e such that: Evaluation of head e won't finish but last e will
there exists e such that: Evaluation of last e won't finish but head e will
there exists e such that: Evaluation of length e won't finish but last e will
Seems clear to me that 2 is true, but I can't see how 1 or 3 can be true.
My thinking is that in order to calculate the length of a list you need to get to the last one, making 1 and 3 impossible
Since this is a test question, I won't answer it directly, but instead, here are some hints; it'd be better if you work this out yourself.
Since we're talking about computations that don't terminate, it might be useful to define one such computation. However, if this confuses you you can safely ignore this and refer only to examples that don't include this.
-- `never` never terminates when evaluated, and can be any type.
never :: a
never = never
Question 1
Consider the list [never, 1], or alternatively the list [last [1..], 1] as suggested by #chi.
Question 2
Consider the list [1..], or alternatively the list [1, never].
Question 3
Consider the definition of length:
length [] = 0
length (_:xs) = 1 + length xs
Under what conditions does length not terminate? How does this relate to last?
i was given a homework in Haskell in which i should program a module, which helps detect prime numbers from a list, say :
[2,3,4,5,6,7,8,9,10]
For the homework, I should iterate through every elements of this list, and eliminate all of it's multiples. Example, I go at number 2, I should eliminate 4,6,8,10. Then go to number 3 and delete 6 and 9, and so on until the end, return the list with prime numbers only.
I have an idea of using function map, but I'm stuck at this place (I'm pretty new to Haskell, though)
Yes, it is my homework, but no, i don't have to do it, it's just practicing. So I'm thankful for any help.
Instead of using a map (I don't think that's possible without doing some pre-processing), you can roll your own function:
sieveWith _ [] = []
sieveWith ss (x:xs) | any ((==) 0 . mod x) ss = sieveWith ss xs
| otherwise = x : (sieveWith (x:ss) xs)
and:
sieve = sieveWith []
Now if you call sieve:
*Main> sieve [2,3,4,5,6,7,8,9,10]
[2,3,5,7]
The function works with a variable (the first one) that is passed through the function calls and each time a value is picked, added to the list. A value is picked if no modulo operation on the variable list yields a zero (second guard). In case any of the modulo's yields zero, the value is simply omitted.
I'm trying to write a function in Haskell that calculates all factors of a given number except itself.
The result should look something like this:
factorlist 15 => [1,3,5]
I'm new to Haskell and the whole recursion subject, which I'm pretty sure I'm suppoused to apply in this example but I don't know where or how.
My idea was to compare the given number with the first element of a list from 1 to n div2
with the mod function but somehow recursively and if the result is 0 then I add the number on a new list. (I hope this make sense)
I would appreciate any help on this matter
Here is my code until now: (it doesn't work.. but somehow to illustrate my idea)
factorList :: Int -> [Int]
factorList n |n `mod` head [1..n`div`2] == 0 = x:[]
There are several ways to handle this. But first of all, lets write a small little helper:
isFactorOf :: Integral a => a -> a -> Bool
isFactorOf x n = n `mod` x == 0
That way we can write 12 `isFactorOf` 24 and get either True or False. For the recursive part, lets assume that we use a function with two arguments: one being the number we want to factorize, the second the factor, which we're currently testing. We're only testing factors lesser or equal to n `div` 2, and this leads to:
createList n f | f <= n `div` 2 = if f `isFactorOf` n
then f : next
else next
| otherwise = []
where next = createList n (f + 1)
So if the second parameter is a factor of n, we add it onto the list and proceed, otherwise we just proceed. We do this only as long as f <= n `div` 2. Now in order to create factorList, we can simply use createList with a sufficient second parameter:
factorList n = createList n 1
The recursion is hidden in createList. As such, createList is a worker, and you could hide it in a where inside of factorList.
Note that one could easily define factorList with filter or list comprehensions:
factorList' n = filter (`isFactorOf` n) [1 .. n `div` 2]
factorList'' n = [ x | x <- [1 .. n`div` 2], x `isFactorOf` n]
But in this case you wouldn't have written the recursion yourself.
Further exercises:
Try to implement the filter function yourself.
Create another function, which returns only prime factors. You can either use your previous result and write a prime filter, or write a recursive function which generates them directly (latter is faster).
#Zeta's answer is interesting. But if you're new to Haskell like I am, you may want a "simple" answer to start with. (Just to get the basic recursion pattern...and to understand the indenting, and things like that.)
I'm not going to divide anything by 2 and I will include the number itself. So factorlist 15 => [1,3,5,15] in my example:
factorList :: Int -> [Int]
factorList value = factorsGreaterOrEqual 1
where
factorsGreaterOrEqual test
| (test == value) = [value]
| (value `mod` test == 0) = test : restOfFactors
| otherwise = restOfFactors
where restOfFactors = factorsGreaterOrEqual (test + 1)
The first line is the type signature, which you already knew about. The type signature doesn't have to live right next to the list of pattern definitions for a function, (though the patterns themselves need to be all together on sequential lines).
Then factorList is defined in terms of a helper function. This helper function is defined in a where clause...that means it is local and has access to the value parameter. Were we to define factorsGreaterOrEqual globally, then it would need two parameters as value would not be in scope, e.g.
factorsGreaterOrEqual 4 15 => [5,15]
You might argue that factorsGreaterOrEqual is a useful function in its own right. Maybe it is, maybe it isn't. But in this case we're going to say it isn't of general use besides to help us define factorList...so using the where clause and picking up value implicitly is cleaner.
The indentation rules of Haskell are (to my tastes) weird, but here they are summarized. I'm indenting with two spaces here because it grows too far right if you use 4.
Having a list of boolean tests with that pipe character in front are called "guards" in Haskell. I simply establish the terminal condition as being when the test hits the value; so factorsGreaterOrEqual N = [N] if we were doing a call to factorList N. Then we decide whether to concatenate the test number into the list by whether dividing the value by it has no remainder. (otherwise is a Haskell keyword, kind of like default in C-like switch statements for the fall-through case)
Showing another level of nesting and another implicit parameter demonstration, I added a where clause to locally define a function called restOfFactors. There is no need to pass test as a parameter to restOfFactors because it lives "in the scope" of factorsGreaterOrEqual...and as that lives in the scope of factorList then value is available as well.
I am very bad at wording things, so please bear with me.
I am doing a problem that requires me to generate all possible numbers in the form of a lists of lists, in Haskell.
For example if I have x = 3 and y = 2, I have to generate a list of lists like this:
[[1,1,1], [1,2,1], [2,1,1], [2,2,1], [1,1,2], [1,2,2], [2,1,2], [2,2,2]]
x and y are passed into the function and it has to work with any nonzero positive integers x and y.
I am completely lost and have no idea how to even begin.
For anyone kind enough to help me, please try to keep any math-heavy explanations as easy to understand as possible. I am really not good at math.
Assuming that this is homework, I'll give you the part of the answer, and show you how I think through this sort of problem. It's helpful to experiment in GHCi, and build up the pieces we need. One thing we need is to be able to generate a list of numbers from 1 through y. Suppose y is 7. Then:
λ> [1..7]
[1,2,3,4,5,6,7]
But as you'll see in a moment, what we really need is not a simple list, but a list of lists that we can build on. Like this:
λ> map (:[]) [1..7]
[[1],[2],[3],[4],[5],[6],[7]]
This basically says to take each element in the array, and prepend it to the empty list []. So now we can write a function to do this for us.
makeListOfLists y = map (:[]) [1..y]
Next, we need a way to prepend a new element to every element in a list of lists. Something like this:
λ> map (99:) [[1],[2],[3],[4],[5],[6],[7]]
[[99,1],[99,2],[99,3],[99,4],[99,5],[99,6],[99,7]]
(I used 99 here instead of, say, 1, so that you can easily see where the numbers come from.) So we could write a function to do that:
prepend x yss = map (x:) yss
Ultimately, we want to be able to take a list and a list of lists, and invoke prepend on every element in the list to every element in the list of lists. We can do that using the map function again. But as it turns out, it will be a little easier to do that if we switch the order of the arguments to prepend, like this:
prepend2 yss x = map (x:) yss
Then we can do something like this:
λ> map (prepend2 [[1],[2],[3],[4],[5],[6],[7]]) [97,98,99]
[[[97,1],[97,2],[97,3],[97,4],[97,5],[97,6],[97,7]],[[98,1],[98,2],[98,3],[98,4],[98,5],[98,6],[98,7]],[[99,1],[99,2],[99,3],[99,4],[99,5],[99,6],[99,7]]]
So now we can write that function:
supermap xs yss = map (prepend2 yss) xs
Using your example, if x=2 and y=3, then the answer we need is:
λ> let yss = makeListOfLists 3
λ> supermap [1..3] yss
[[[1,1],[1,2],[1,3]],[[2,1],[2,2],[2,3]],[[3,1],[3,2],[3,3]]]
(If that was all we needed, we could have done this more easily using a list comprehension. But since we need to be able to do this for an arbitrary x, a list comprehension won't work.)
Hopefully you can take it from here, and extend it to arbitrary x.
For the specific x, as already mentioned, the list comprehension would do the trick, assuming that x equals 3, one would write the following:
generate y = [[a,b,c] | a<-[1..y], b<-[1..y], c <-[1..y]]
But life gets much more complicated when x is not predetermined. I don't have much experience of programming in Haskell, I'm not acquainted with library functions and my approach is far from being the most efficient solution, so don't judge it too harshly.
My solution consists of two functions:
strip [] = []
strip (h:t) = h ++ strip t
populate y 2 = strip( map (\a-> map (:a:[]) [1..y]) [1..y])
populate y x = strip( map (\a-> map (:a) [1..y]) ( populate y ( x - 1) ))
strip is defined for the nested lists. By merging the list-items it reduces the hierarchy so to speak. For example calling
strip [[1],[2],[3]]
generates the output:
[1,2,3]
populate is the tricky one.
On the last step of the recursion, when the second argument equals to 2, the function maps each item of [1..y] with every element of the same list into a new list. For example
map (\a-> map (:a:[]) [1..2]) [1..2])
generates the output:
[[[1,1],[2,1]],[[1,2],[2,2]]]
and the strip function turns it into:
[[1,1],[2,1],[1,2],[2,2]]
As for the initial step of the recursion, when x is more than 2, populate does almost the same thing except this time it maps the items of the list with the list generated by the recursive call. And Finally:
populate 2 3
gives us the desired result:
[[1,1,1],[2,1,1],[1,2,1],[2,2,1],[1,1,2],[2,1,2],[1,2,2],[2,2,2]]
As I mentioned above, this approach is neither the most efficient nor the most readable one, but I think it solves the problem. In fact, theoritically the only way of solving this without the heavy usage of recursion would be building the string with list comprehension statement in it and than compiling that string dynamically, which, according to my short experience, as a programmer, is never a good solution.