as the title says, I'm trying to recode this function but I keep getting an error that says that the type that I output doesnt match the expected type. Could someone help me with this? Here's my code :
myPartition :: (a -> Bool) -> [a] -> ([a], [a])
myPartition f (x:xs) = if f x
then (x : myPartition f xs, [])
else ([], x : myPartition f xs)
myPartition _ [] = ([], [])
Also, im not authorized to use any function of the standard library
The main problem is that your function checks if f x holds, and if so constructs a 2-tuple where it will write the entire result of the recursive call. That result will be a 2-tuple as well, so you try to use a 2-tuple as an element in a 2-tuple as an element in a …
You should make a recursive call to obtain a 2-tuple of elements for the rest of the list, and the prepend the item to any of the two, so:
myPartition :: (a -> Bool) -> [a] -> ([a], [a])
myPartition p = go
where go (x:xs)
| p x = (…, …)
| otherwise = (…, …)
where (pa, pb) = go xs
go [] = ([], [])
where you still need to fill in the … parts.
Currently, I am making a function that can take the values in two lists, compare them, and print any similar values. If a value is duplicated in both lists, it is not printed a second time.
EXAMPLE
INPUT: commons [1,2,2,3,4] [2,3,4,5,2,6,8]
EXPECTED OUTPUT: [2,3,4]
What I currently have causes a repeated values in both lists to repeat in the output. So, in the above example, the 2 would print twice.
Here is the current code I am working on:
commons :: Eq a => [a] -> [a] -> [a]
commons [] [] = []
commons x y = commons_Helper x y
commons_Helper :: Eq a => [a] -> [a] -> [a]
commons_Helper [] [] = []
commons_Helper x [] = []
commons_Helper [] y = []
commons_Helper (x:xs) y =
if elem x y then x : commons_Helper xs y
else commons_Helper xs y
Any and all help would be greatly appreciated.
EDIT: This must remain as commons :: Eq a => [a] -> [a] -> [a], and I cannot import and libraries
You could make your traversal of the xs list a stateful one, the state keeping track of elements that have been already seen. The state begins life as an empty list.
It is possible to do that by adding a 3rd parameter to your helper function, which currently is not very useful.
commons_Helper :: Eq a => [a] -> [a] -> [a] -> [a]
commons_Helper [] ys st = []
commons_Helper (x:xs) ys st =
if (elem x ys && (not $ elem x st)) -- extra test here
then x : (commons_Helper xs ys (x:st))
else commons_Helper xs ys st
commons :: Eq a => [a] -> [a] -> [a]
commons xs ys = commons_Helper xs ys []
This state-based technique is very common in Haskell. There is even a library function: mapAccumL :: (s -> a -> (s, b)) -> s -> [a] -> (s, [b]) to support it.
I want to write a polymorphic function that inputs two lists and tells me whether these two lists contain a common element. My attempt at writing this function is as follows:
overlaps :: (Eq a) => [a] -> [a] -> Bool
overlaps x:xs y:ys
| x `is_element_of` ys = True
| otherwise = False
where
is_element_of :: (Eq a) => a -> [a] -> Bool
is_element_of e list = case list of
[] -> False
x: xs -> e == x || e `is_element_of` xs
However this isn't working... Is it possible to pattern match against two lists? Is this a possible way of writing this function?
Your function is_elem_of already exists in the Data.List package as elem. Using that, overlaps is easy to write.
overlaps [] _ = False
overlaps (x:xs) ys = x `elem` ys || overlaps xs ys
As you can tell, it is possible to pattern match on lists. If you want to write the function without pattern matching on lists, you can use the foldr function.
overlaps xs ys = foldr (\x acc -> x `elem` ys || acc) False xs
I think you would want something like this (untested):
overlaps :: (Eq a) => [a] -> [a] -> Bool
overlaps [] _ = False
overlaps _ [] = False
overlaps (x:xs) list = x `myelem` list || overlaps xs list
myelem :: (Eq a) => a -> [a] -> Bool
myelem _ [] = False
myelem x (y:ys) = x == y || myelem x ys
AFAIK using the pattern matching appropach is more idiomatic.
I'm trying to create a new implementation of the elem function in Haskell using the foldr function.
So far I have this:
count :: Eq a => a -> [a] -> Integer
count x (y:ys) = foldl (\counter y -> if y == x then counter + 1 else counter) 0 ys
count _ [] = 0
elem' :: Eq a => a -> [a] -> Bool
elem' x (y:ys) = foldr (\i elem-> if (count x (y:ys)) > 0 then True else False) False ys
elem' _ [] = False
The count function is counting the number of occurances of x (another function I wrote) using foldl. This works fine for finite lists, but the problem is that I want to take advantage of the foldr lazy computation of an infinite list. If I try to use an infinite list as input the program hangs forever.
Basically I want to "break out" once I find any instance of x in the list and return true, otherwise return false.
Thanks for the help.
Let's start with the basic skeleton on the foldr pattern:
elem :: Eq a => [a] -> Bool
elem x xs = foldr kons knil xs
When foldr sees [], it will return knil. Since nothing is an element of the empty list, we conclude that
knil = False
When foldr kons False sees a list a : as, it returns kons a (foldr kons False as). We can assume inductively that foldr kons False as = elem x as, so we seek to solve for kons in
elem x (a : as) = kons a (elem x as)
I bet you can finish up by coming up with the definition of kons. Watch out for Boolean short-circuit behavior to make this efficient and avoid problems with infinite lists.
I would like to put the 2 functions (color and check) into the most general form
Eq a => ....
But I don't know how to do that.
This is a very simple graph: each node has 2 neighbours, and any adjacent nodes must have different colors
color :: [(Int, Int)] -> [(Int, Int)] -> Bool
color x [] = True
color a ((x,y):rest) =
if check a x == check a y
then False
else color a rest
check :: [(Int, Int)] -> Int -> Int
check [] x = 999
check ((x,y):rest) p =
if x == p
then y
else check rest p
At the end, colors gives you True or False
Main> colors [('a',"purple"),('b',"green"),('c',"blue")] [('a','b'),('b','c'),('c','a')]
True
Main> colors [('a',"purple"),('b',"green"),('c',"purple")] [('a','b'),('b','c'),('c','a')]
False
Main> colors [('1',"purple"),('2',"green"),('3',"blue")] [('1','2'),('2','3'),('3','1')]
True
Main> colors [('1',"4"),('2',"5"),('3',"6")] [('1','2'),('2','3'),('3','1')]
True
Main> colors [('1',"4"),('2',"4"),('3',"5")] [('1','2'),('2','3'),('3','1')]
False
Any help is welcome (+ if you can fix x = 999 into False).
For starters, the reason you can't generalize the Int to an Eq a is because of the 999 hard-coded in check. If you just leave some random value in there, you must know its type, so you cannot generalize the function beyond that (well, in this particular case, you can generalize to Eq a, Num a, but not more).
So, the answer is to not use some arbitrary value, but instead wrap the return of check into a type that has a "failure" case, namely Maybe.
Renaming the variables to follow Haskell conventions, and giving the functions a bit more elucidating names, we get:
canColor :: Eq a => [(a, a)] -> [(a, a)] -> Bool
canColor _ [] = True
canColor xs ((x,y):rest) =
if findNeighbour xs x == findNeighbour xs y
then False
else canColor xs rest
findNeighbour :: Eq a => [(a, a)] -> a -> Maybe a
findNeighbour [] _ = Nothing
findNeighbour ((x,y):rest) z =
if x == z
then Just y
else findNeighbour rest z
The idea here is that findNeighbour returns Nothing if it can't find anything, or Just 23 if it finds 23 (or whatever it finds).
As it happens, findNeighbour is already defined: it's called lookup. So, you could rewrite your code as:
canColor :: Eq a => [(a, a)] -> [(a, a)] -> Bool
canColor _ [] = True
canColor xs ((x,y):rest) =
if lookup x xs == lookup y xs
then False
else canColor xs rest
Now, we note that you are basically checking a predicate against all items in a list. There's a function for this: all. So, we can shorten the code to:
canColor :: Eq a => [(a, a)] -> Bool
canColor xs = all (\(x, y) -> lookup x xs /= lookup y xs) xs