The point of the following function is to take in a list and split the list into a tuple of 2 lists. The first list will maintain even indexed items and the second will maintain odd indexed items. "Pos" is the position currently at. (0 is being passed in on function call). The initial tuple of lists passed in is ([],[])
split :: [Integer] -> ([Integer],[Integer]) -> Integer -> ([Integer], [Integer])
split [] (x,y) _ = (x,y)
split (x:xs) ((y:ys),(z:zs)) pos
| pos `mod` 2 == 0 = doSplit xs ((y:ys) ++ [x], (z:zs)) (pos + 1)
| otherwise = doSplit xs ((y:ys), (z:zs) ++ [x]) (pos + 1)
Haskell is reporting
*** Exception: split.hs:(113,1)-(116,73): Non-exhaustive patterns in function split
I understand that it believes that I have not covered "some case" that should be covered, however I feel I have covered all cases.
If the list is empty -> return the tuple of lists that was passed in
Otherwise -> tack x onto one of the lists and recurse on xs.
From my point of view, this function is strictly decreasing until xs becomes [] in which case it stops.
Am I missing something?
There is no match when the first list is nonempty but one (or both) of the lists in the tuple argument are empty e.g.
split [1] ([], [])
however your second clause doesn't seem to require that either list in the tuple is non-empty so you could change it to:
split (x:xs) (ys,zs) pos
| pos `mod` 2 == 0 = doSplit xs (ys ++ [x], zs) (pos + 1)
| otherwise = doSplit xs (ys, zs ++ [x]) (pos + 1)
Related
I have an if-else statement, and in the else block I want it to first recurse to the function, except for the last two elements of the list, and then return two elements.
In the following function, after the if-else statement, I have 2 lines of code. however this doesnt compile. I believe the compiler reads these two lines as a single line of code. How do you fix that?
doubleEveryOther :: [Integer] -> [Integer] --outputs the input list, but every 2nd element(from the right) is doubled
doubleEveryOther [] = []
doubleEveryOther x = if (length x <2)
then
x
else
doubleEveryOther init (init x) -- These two lines
[2*last(init x), last x] -- These two lines
The compiler says:
* Couldn't match expected type: [Integer]
with actual type: [a0] -> [a0]
* Probable cause: `init' is applied to too few arguments
In the first argument of `doubleEveryOther', namely `init'
In the expression: doubleEveryOther init (init x)
In the expression:
[doubleEveryOther init (init x), 2 * last (init x), last x]
|
19 | [doubleEveryOther init (init x), 2*last(init x), last x]
|
You can not return two lists. If you have two results you want to combine, you use some function, like (++) :: [a] -> [a] -> [a].
That being said, you here don't need this. You can work with simple pattern matching:
doubleEveryOtherFromLeft :: Num a => [a] -> [a]
doubleEveryOtherFromLeft (x:y:xs) = 2*x : y : doubleEveryOtherFromLeft xs
doubleEveryOtherFromLeft xs = xs
then our doubleEveryOther can reverse the list twice:
doubleEveryOther:: Num a => [a] -> [a]
doubleEveryOther = reverse . doubleEveryOtherFromLeft . reverse
I think you are just missing the append operator ++:
doubleEveryOther (init (init x))
++ [2 * last (init x), last x]
I have an if-else statement, and in the else block I want it to first
recurse to the function, except for the last two elements of the list,
and then return two elements
OK. I sort of understand what you're doing. The function name is good - the best name is verb-noun, here doubleEveryOther. However, the code looks a lot like Lisp, probably Scheme - the repeated use of init gives it away. That's not how you write Haskell. (I also write Lisp in Haskell syntax too much...)
Haskell recursion works using pattern matching.
lst = [2,3,4]
1 : [2,3,4] -- [1,2,3,4]
lst = [1,2,3,4]
(x:xs) = lst -- x is 1, xs = [2,3,4]
So, in this case, you want to match your list against x:y:xs:
lst = [1,2,3,4]
(x:y:xs) = lst -- x is 1, y is 2, xs=[3,4]
Hence:
doubleEveryOther :: Num a => [a] -> [a]
doubleEveryOther [] = []
doubleEveryOther [x] = [2*x]
doubleEveryOther (x:y:xs) = (2*x):doubleEveryOther xs
Please note the number of special cases which need to be handled. If I am given an empty list, I should return an empty list. If I am given a single value, I need to double it (in analogy to your if .. else clause). If I am given two or more values, this matches x=first, y=second, xs=[] or more.
As for returning more than one value, you can return only one thing from a function. It can be a single value, a single tuple, a single list, and so on.
In this case, you have written a function which says doubleEveryOther - good - but then you want to return the last two values unchanged. You would be better taking off the last two values, running the simple doubleEveryOther and then bolting the last two values on the end. Otherwise, you are overburdening your function.
I would like to ask how to create all combinations of elements of a certain length by intentional lists in Haskell? Here is the example:
Function combo is taking two arguments list of elements - xs and value - n, the goal is to create all possible combinations of elements in xs of length n by intentional lists.
For example:
combo [1,2,3] 2
should return
[[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]
Thank you in advance for any help
This could be done using a combinatorics library, but can also easily be done yourself.
A small example I made:
import Data.List
permutations' _ [] = []
permutations' 0 _ = []
permutations' n xs | n > length xs = error "n can't be larger than length of input"
| otherwise = permute n xs []
permute 0 xs ys = [ys]
permute n xs ys = concatMap (\x -> foo (n-1) (x `delete` xs) (ys ++ [x])) xs
The 'magic' is happening in premute where a simple combinatorics is applied.
You start off with an empty list of solutions which is extended until the character limit n is reached. The input xs e.g. [1,2,3] is mapped, thus each character in xs is fed into the lambda function. In the lambda the x is appended to the already existing result. In the first loop ys is empty thus only x is added. In subsequent calls to permute the xs list is shrunk and ys is appended with the value that xs is shrunk with. Thus growing the result until char limit is reached and subsequently removing characters from xs to prevent duplicate entries.
A walkthrough of permute 2 [1,2,3] [] might look like this:
(\1 -> foo (2-1) [2,3] [] ++ [1])
- (\2 -> foo (1-1) [3] [1] ++ [2])
- [1,2], since we hit the first pattern where n = 0
- (\3 -> foo (1-1) [2] [1] ++ [3])
- [1,3], since we hit the first pattern where n = 0
(\2 ....
(\3 ....
This is probably a stupid question, but I've been stuck on this problem for some hours now.. I have made a genetic algorithm but thought that I could try to improve it a bit. I want to make a fitness function that compare two lists of digits and returns a value. If both lists contains a number that is the same and are in the same "place" the function should return + 2. If the lists contains a number that is the same but in the wrong place it should return + 1.
I've made two different functions which both fulfill one of these tasks, but I can't manage to incorperate them into one function. Here are the functions:
samePlace _ [] = 0
samePlace [] _ = 0
samePlace (x:xs) (y:ys)
| x == y = (sP xs ys) + 2
| otherwise = sP xs (ys)
This function returns +2 for every digit that is the same and is in the right place.
notSamePlace [] _ = 0
notSamePlace _ [] = 0
notSamePlace (x:xs) (ys)
| elem x (ys) = (notSamePlace xs ys) + 1
| otherwise = (notSamePlace xs ys)
This function returns + 1 is one of the digits in the first list exists in the second list.
The problem I got is that the same-place function requires to split up the two lists and go through them one digit at a time to compare them while the not-the-same-place function needs to keep the second list intact without splitting it up in a head and tail. Would be so thankful if someone could point me in the right direction on how to go about this problem.
Also, my thought was that this function could improve the time it takes to find the solution in the genetic algorithm. If my solution is to find the string "hello world", my thought is that an individual with the gene "leolh owdrl" should have more fitness than a gene that looks like "hFz%l r0M/z". In my program so far the first gene would have a fitness value of 1 (because the 'space' is the only character in the same place as the targets characters) but the second gene has the 'h' and the 'space' right so it would be given a fitness value of 2. Is this a good thought or not?
Thanks!
Below function uses zip to index every character, which allows to pass the full second list into recursive calls.
places :: String -> String -> Int
places _ [] = 0
places [] _ = 0
places xs ys = zippedPlaces (zip xs [1..length xs]) (zip ys [1..length ys])
zippedPlaces :: [(Char, Int)] -> [(Char, Int)] -> Int
zippedPlaces [] _ = 0
zippedPlaces (x:xs) ys =
let match = filter (\(num, i) -> fst x == num) ys
in case match of
[] -> zippedPlaces xs ys
(a:_) -> (if snd a == snd x then 2 else 1) + zippedPlaces xs ys
Assumes that no list contains duplicates:
place [] _ = 0
place _ [] = 0
place (x:xs) (y:ys) = place xs ys +
if x == y then 1 else (if elem x ys then 2 else 0) + (if elem y xs then 2 else 0)
I have been working with Haskell for a little over a week now so I am practicing some functions that might be useful for something. I want to compare two lists recursively. When the first list appears in the second list, I simply want to return the index at where the list starts to match. The index would begin at 0. Here is an example of what I want to execute for clarification:
subList [1,2,3] [4,4,1,2,3,5,6]
the result should be 2
I have attempted to code it:
subList :: [a] -> [a] -> a
subList [] = []
subList (x:xs) = x + 1 (subList xs)
subList xs = [ y:zs | (y,ys) <- select xs, zs <- subList ys]
where select [] = []
select (x:xs) = x
I am receiving an "error on input" and I cannot figure out why my syntax is not working. Any suggestions?
Let's first look at the function signature. You want to take in two lists whose contents can be compared for equality and return an index like so
subList :: Eq a => [a] -> [a] -> Int
So now we go through pattern matching on the arguments. First off, when the second list is empty then there is nothing we can do, so we'll return -1 as an error condition
subList _ [] = -1
Then we look at the recursive step
subList as xxs#(x:xs)
| all (uncurry (==)) $ zip as xxs = 0
| otherwise = 1 + subList as xs
You should be familiar with the guard syntax I've used, although you may not be familiar with the # syntax. Essentially it means that xxs is just a sub-in for if we had used (x:xs).
You may not be familiar with all, uncurry, and possibly zip so let me elaborate on those more. zip has the function signature zip :: [a] -> [b] -> [(a,b)], so it takes two lists and pairs up their elements (and if one list is longer than the other, it just chops off the excess). uncurry is weird so lets just look at (uncurry (==)), its signature is (uncurry (==)) :: Eq a => (a, a) -> Bool, it essentially checks if both the first and second element in the pair are equal. Finally, all will walk over the list and see if the first and second of each pair is equal and return true if that is the case.
I'm pretty new to Haskell, and I'm having a little trouble. I'm trying to implement a function that takes a list, and an int. the int is supposed to be the index k at which the list is split into a pair of lists. The first one containing the first k elements of the list, and the second from k+1 to the last element. Here's what I have so far:
split :: [a] -> Int -> ([a], [a])
split [] k = error "Empty list!"
split (x:[]) k = ([x],[])
split xs k | k >= (length xs) = error "Number out of range!"
| k < 0 = error "Number out of range!"
I can't actually figure out how to do the split. Any help would be appreciated.
First of all, note that the function you are trying to construct is already in the standard library, in the Prelude - it is called splitAt. Now, directly looking at its definition is confusing, as there are two algorithms, one which doesn't use the standard recursive structure at all -splitAt n xs = (take n xs, drop n xs) - and one that is hand-optimized making it ugly. The former makes more intuitive sense, as you are simply taking a prefix and a suffix and putting them in a pair. However, the latter teaches more, and has this overall structure:
splitAt :: Int -> [a] -> ([a], [a])
splitAt 0 xs = ([], xs)
splitAt _ [] = ([], [])
splitAt n (x:xs) = (x:xs', xs'')
where
(xs', xs'') = splitAt (n - 1) xs
The basic idea is that if a list is made up of a head and a tail (it is of the form x:xs), then the list going from index k+1 onwards will be the same as the list going from k onwards once you remove the first element - drop (k + 1) (x : xs) == drop k xs. To construct the prefix, you similarly remove the first element, take a smaller prefix, and stick the element back on - take (k + 1) (x : xs) == x : take k xs.
What about this:
splitAt' = \n -> \xs -> (take n xs, drop n xs)
Some tests:
> splitAt' 3 [1..10]
> ([1,2,3],[4,5,6,7,8,9,10])
> splitAt' 0 [1..10]
> ([],[1,2,3,4,5,6,7,8,9,10])
> splitAt' 3 []
> ([],[])
> splitAt' 11 [1..10]
> ([1,2,3,4,5,6,7,8,9,10],[])
> splitAt' 2 "haskell"
> ("ha","skell")
Basically, you need some way of passing along partial progress as you recurse through the list. I used a second function that takes an accumulator parameter; it is called from split and then calls itself recursively. There are almost certainly better ways..
EDIT: removed all the length checks., but I believe the use of ++ means it's still O(n^2).
split xs k | k < 0 = error "Number out of range!"
split xs k = ssplit [] xs k
ssplit p xs 0 = (p, xs)
ssplit p (x:xs) k = ssplit (p++[x]) xs (k-1)
ssplit p [] k = error "Number out of range!"
to get the behavior in the original post or
ssplit p [] k = (p,[])
To get the more forgiving behavior of the standard splitAt function.
A common trick for getting rid of quadratic behavior in building a list is to build it up backwards, then reverse it, modifying Mark Reed's solution:
split xs k | k < 0 = error "Number out of range!"
split xs k = (reverse a, b)
where
(a,b) = ssplit [] xs k
ssplit p xs 0 = (p, xs)
ssplit p (x:xs) k = ssplit (x:p) xs (k-1)
ssplit p [] k = error "Number out of range!"
The error check in ssplit is fine since won't get checked (one of the earlier patterns will match) unless there is an actual error.
In practice you might want to add a few strictness annotations to ssplit to manage stack growth, but that's a further refinement.
See splitAt in the prelude:
ghci> :t flip splitAt
flip splitAt :: [a] -> Int -> ([a], [a])
ghci> flip splitAt ['a'..'j'] 5
("abcde","fghij")