I am trying to separate elements of a list into to further lists, one for the odd and one for even numbers.
For Example,
input: [1,2,3,4,10]
output: ([2,4,10],[1,3])
sepList :: [Int]->([Int],[Int])
sepList [] = ([],[])
sepList (x:xs) | (x mod 2) ==0 = (([x],[]) ++ sepList xs)
| (x mod 2) /=0 = (([],[x]) ++ sepList xs)
| otherwise = ([],[])
It gives error on ...++ sepList xs
anyone could guide me here?
The operator++ is used to concatenate 2 lists and neither of your arguments to ++ is a list,
([x],[]) ++ sepList xs
both ([x],[]) and sepList xs are pairs of lists. So what you want is to pattern match on sepList xs e.g. using a let binding,
let (ys,zs) = sepList xs in
and then return,
(x:ys,zs)
You aren't concatenating two lists; you want to add a single element to a list, selected from the tuple output of the recursive call. Don't use (++); use (:).
sepList (x:xs) = let (evens, odds) = sepList xs
in if even x
then (x:evens, odds)
else (evens, x:odds)
More simply, though, sepList = partition even. (partition can be found in Data.List.)
There are two answers so far which suggest basically doing this by hand (by pattern-matching on the result of the recursive call), but there is actually an operator already defined for the types that you're working with that does exactly what you want! Lists form a monoid with (<>) = (++), but you don't have two lists: you have two pairs of lists. Happily, the type of pairs are also a monoid if each element of the pair is a monoid: (a,b) <> (c,d) = (a <> c, b <> d). So, you can simply replace your ++ call with <>, which will result in concatenating the corresponding lists in your pairs.
For enthusiasts, following one line will also work for separating list in even and odd.
sepList xs = (filter even xs , filter odd xs)
import Data.List
sepList :: [Int]->([Int],[Int])
sepList = partition even
sepList [1,2,3,4,10]
In this case i would use an accumulator to create the tuple containing the two lists.In our case the accumulator is ([],[]).
split::[Int]->([Int],[Int])
split ls= go ([],[]) ls where
go accu [] = accu
go (odd,even) (x:xs) | x `mod` 2==0 = go (x:odd,even) xs
| otherwise = go (odd, x:even) xs
As you can see the elements need to be reversed since we are pushing on top of our lists with the : operator.
I do not know if this is optimal but i would write it like this with reverse:
module Split where
split::[Int]->([Int],[Int])
split ls=let rev tupl=(reverse . fst $ tupl ,reverse .snd $ tupl) in
rev $ go ([],[]) ls where
go accu [] = accu
go (odd,even) (x:xs) | x `mod` 2==0 = go (x:odd,even) xs
| otherwise = go (odd, x:even) xs
I suppose to input a list of words. If a word's last letter is the same as the first letter of another word, then we connect them and output a list of lists, which contain all possible connections.
Example: convert(["apple","elephant","eraser", "tower","rank"]) will give
[["elephant", "eraser"], ["tower"], ["rank"], ["rank"], []]
I implemented my code as following:
convert :: [String] -> [[String]]
convert [] = []
convert [x] = []
convert (x : xs) = if last x == head (head xs)
then [head xs] : [] : convert (x : (tail xs))
else convert (x : (tail xs))
But this can only check the first element. How can I loop through the whole list and check each word?
===========================================================================
Ok. I have it done.
convert :: [String] -> [[String]]
convert [] = []
convert (x:xs) = [u | u <- xs, last x == head u] : convert (xs)
Im very new to haskell and would like to know if theres a basic case for not going out of the list when going threw it!
For example in this code im trying to make a list where it compares the number on the right, and it if its bigger it stays on the list, otherwise we remove it, but it keeps giving me Prelude.head:empty list, since its comparing to nothing in the end im assuming. I've tried every base case i could think off... can anyone help me?
maiores:: [Int]->[Int]
maiores [] = []
maiores (x:xs) | x > (head xs) = [x] ++ [maiores xs)
| otherwise = maiores xs
If your function is passed a list with one element, it will match (x:xs), with xs matching []. Then you end up with head [] and thus your error. To avoid this, add an additional base case maiores (x:[]) = ... between your two existing cases, and fill it in appropriately.
Also: you can write [x] ++ maiores xs as x : maiores xs, which is more natural because you deconstruct a : and then immediately reconstruct it with the modified value, as opposed to indirectly using ++.
Never use head or tail in your code, unless you can't avoid it. These are partial functions, which will crash when their input is empty.
Instead, prefer pattern matching: instead of
foo [] = 4
foo (x:xs) = x + head xs + foo (tail xs)
write
foo [] = 4
foo (x1:x2:xs) = x1 + x2 + foo xs
Now, if we turn on warnings with -Wall, GHC will suggest that the match in not exhaustive: we forgot to handle the [_] case. So, we can fix the program accordingly
foo [] = 4
foo [x] = x
foo (x1:x2:xs) = x1 + x2 + foo xs
Just make pattern matching more specific. Since (:) is right associative:
maiores:: [Int]->[Int]
maiores [] = []
maiores (x : y : xs) | x > y = [x] ++ maiores (y:xs)
maiores (_ : xs) = maiores xs
I've seen the other threads about missing split function but I didn't want to peek as I do this for learning purposes and want to figure out myself. So here it is:
split :: Char -> String -> [String]
split c xs | null f = []
| otherwise = f : split c s'
where (f,s) = break (== c) xs
s' | null s = s
| otherwise = tail s
It seems to work fine (please tell me if anything is wrong with it) but when I use a splitting character that is not in the string then the function returns a list with a single element of the original string whereas I want it to return an empty list. I can't figure out how to do it.
Any ideas?.
You can simply write a wrapper function, changing the result of your original one:
split' x xs = go (split x xs) where
go [_] = []
go ys = ys
There are many ways to write a split function, e.g.
split x xs = foldl' go [[]] xs where
go (ys:yss) y | y == x = []:ys:yss
| otherwise = (y:ys):yss
or
import Data.List
split x xs = map tail $ groupBy (const (/=x)) (x:xs)
I have this function which removes occurrences of a given element within the list of lists.
remove :: Eq a => a -> [[a]] -> [[a]]
remove y [] = error "Can't remove an element from an empty list"
remove y xs = map (filter(/=y)) xs
How would I be able to do the same using List comprehension
Thank you
For each l in xs, add filter (/= xs) l to the resulting list:
remove y xs = [filter (/= y) l | l <- xs]
or, removing filter by nesting comprehensions.
For each xs in xss and for each x in xs, keep x only if it's different from y:
remove y xss = [ [x| x <- xs, x /= y] | xs <- xss]
It's OK if you're just practicing , but your version with map is way better :)
I guess something along the lines of:
remove y ls = [f|l <- ls, let f = filter (/= y) l]
should be fine.
It basicly states that for every binding l you can make in the list ls, add the filtered list f to the resulting list.