Recursive syntax in haskell using and - haskell

I am trying to create a recursive function that takes and input List of List that looks like this: [[1,2], [4], [3], [1]] and returns a Bool. It is supposed to check whether all lists include at least one unique number. I am trying to do this recursively using the two function below.
Function that removes all elements from the first list in the second list:
helper :: Eq a => [a] -> [a] -> [a]
helper a b = filter (`notElem` b) a
Main function:
function :: [[Int]] -> Bool
function [] = True
function (x:y:xs) = (not (null r)) and (function (r ++ xs))
where r = helper(x,y)
However, I get these two errors from the compiler:
Couldn't match expected type ‘(t0 Bool -> Bool) -> Bool -> Bool’
with actual type ‘Bool’
The function ‘not’ is applied to three arguments,
but its type ‘Bool -> Bool’ has only one
In the expression: (not (null r)) and (function (r ++ xs))
In an equation for ‘function’:
function (x : y : xs)
= (not (null r)) and (function (r ++ xs))
where
r = helper (x, y)
I am new to Haskell and not fully comfortable with the Haskell syntax.

First issue - calling a function with multiple arguments. This is done with the following syntax: myFunction a b (not myFunction (a, b)).
The reason for this is that (a, b) is a tuple. Here's a link with some info on tuples
Second issue - you are using and instead of &&
Third issue - you are trying to combine r and xs with ++ but the type of r is [Int] whereas the type of xs is [[Int]]. If your goal is to prepend r to xs then you can do this with :
helper :: Eq a => [a] -> [a] -> [a]
helper a b = filter (`notElem` b) a
function :: [[Int]] -> Bool
function [] = True
function (x:y:xs) = not (null r) && function (r : xs)
where r = helper x y

Related

Trying to code my own 'partition' function in haskell

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.

First element in a list haskell

So i need to do a find2 method that take the first Element out.
For example find2 :: (a -> Bool) -> [a] -> a
and find2 (>4) [1 .. 10]
Should have a the output 5
I am not good with haskell, but i want to learn it.
My first try was
find2 :: (a -> Bool) -> [a] -> a
find2 p [] = []
find2 p (x:xs)
|p x = x+1
|otherwise = finde p xs
but i am getting an error
* Couldn't match expected type `a' with actual type `[a0]'
`a' is a rigid type variable bound by
the type signature for:
find2 :: forall a. (a -> Bool) -> [a] -> a
at C:\\Users\XY\Desctop\XY.hs:30:1-32
* In the expression: []
In an equation for `find2': find2 p [] = []
* Relevant bindings include
p :: a -> Bool
(bound at C:\\Users\XY\Desctop\XY.hs:31:7)
find2 :: (a -> Bool) -> [a] -> a
(bound at C:\\Users\XY\Desctop\XY.hs:31:1)
There is a problem here. There might not be a value in your list for which p holds true. You can see that problem in the base case of your function, when you return an empty list. However, you declared your function to return a single a value, and not a list.
Because of that, you need a way to differentiate a found value from an empty value. For this you can declare your function to return Maybe a instead of a. That way, when you reach the empty list case, you can return Nothing, and if you find the element you were looking for you can return Just x. It would look like this:
find2 :: (a -> Bool) -> [a] -> Maybe a
find2 p [] = Nothing
find2 p (x:xs)
|p x = Just x
|otherwise = find2 p xs
If you're not familiar with the Maybe type, you can read more about it here
If you're ok with erroring when the list contains no satisfactory elements, you can do this:
find p xs = head (filter p xs)
or the equivalent point-free, which I like more
find p = head . filter p
(not this though, it's over the top)
find = (head .) . filter -- obscure, not a good choice
If you want to return it in a Maybe, you can import Data.Maybe and do this:
find p = listToMaybe . filter p
If you want it in a list, this never errors:
find p = take 1 . filter p
You can use dropWhile (not . p) instead of filter p if you like, too.
Manually defining the recursion is fine too, but I think it's work that isn't necessary.

Haskell filter function with multiple parameters

I'm trying to learn Haskell and wondered how to filter a given list, with a function that takes multiple parameters, passing each element of the list with other unchanging elements to the function, to create a new list.
I understand that I can do this to use a bool function to filter the list:
newList = filter theFunction aList
but what happens when the theFunction takes other parameters like this:
theFunction -> elementOfAList -> Int -> Bool
how then could I filter each element of the list, whilst parsing in another element to the function? Any help would be greatly appreciated :)
Edit -> To provide some more information, if I wanted to have a list of integers from [1..10], that get filtered through a function that takes two integers and returns true if the first one is smaller, how could I do that?
In that case you use a partially applied predicate function, like this
-- theFunction :: elementOfAList -> Int -> Bool -- "::" means, "is of type"
newList = filter (flip theFunction i) aList
because
flip theFunction i x = theFunction x i
by the definition of flip, so flip theFunction has the type Int -> elementOfAList -> Bool:
flip :: (a -> b -> c ) -> b -> a -> c
theFunction :: a -> Int -> Bool
flip theFunction :: Int -> a -> Bool
flip theFunction (i :: Int) :: a -> Bool
where i is some Int value defined elsewhere. a is a type variable, i.e. it can be any type, like the type of a list's elements (i.e. for a list aList :: [a] each element has the same type, a).
For example, with theFunction x i = x < i you could call filter (flip theFunction 5) aList, keeping in the resulting list all the elements of aList that are smaller than 5. Normally this would just be written as filter (< 5) aList, with operator sections (of which (< 5) is one example, absolutely equivalent to the flip theFunction 5).
The above filtering will use the same Int value i in calling theFunction for every element x of a list aList. If you wanted to recalculate that Int, it is done with another pattern (i.e., higher-order function),
mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
Suppose you wanted to keep in a list of ints all the elements as they are being found by theFunction. Then you could do it like
theFunction :: elementOfAList -> Int -> Bool
foo :: Int -> [Int] -> [Int]
foo i xs = concat (snd (mapAccumL g i xs)) -- normally written as
-- concat $ snd $ mapAccumL g i xs -- or
-- concat . snd $ mapAccumL g i xs -- or even
-- concat . snd . mapAccumL g i $ xs
where
g acc x -- g :: (acc -> x -> (acc, y)) according to mapAccumL's signature
| theFunction x acc = (x, [x]) -- include `x` in output, and update the acc
| otherwise = (acc, []) -- keep the accumulated value, and skip this `x`
Because both x and acc are used in the same role (the first element of the tuple) they both must be of same type.

How I can set the signature of a function right?

I'm practicing some Haskell to understand the \, case.. of and Maybe better.
I've got this little function here which should return Nothing if the array is empty, Just y if y is equal to the head of the array xs and Just (tail xs) if y is not equal to the head of the array xs.
I set the return type of the function to Maybe a because in one case it should return an Int and in the other an [Int].
funct :: Int -> [Int] -> Maybe a
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just y
else Just (tail xs)
What am I missing? I am getting the error that it couldn't match type a with [Int]. Isn't the a in Maybe a generic or is it influenced by the fact that I "used" the a as an Int in the Just y part?
EDIT: Ok my suggestion was bs, I tested it with Just (tail xs) in the then and else part and I'm still getting the same error.
set the return type of the function to Maybe a because in one case it should return an Int and in the other an [Int].
Haskell is statically typed. Meaning it can not - at runtime - have a different return type. It can only have one return type. a is not an ad hoc type (in the sense that it can be any type at runtime). It means that a will be determined - at compile time - based on the types of other parameters.
For instance you can write: foo :: a -> a -> a to specify that if foo takes two Ints (again known at compile time), the result will be an Int.
You can however use Either a b to say that you will either return a Left a, or a Right b. So you can rewrite it to:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct = \y xs -> case xs of
[] -> Nothing
xs -> if ((head xs) == y)
then Just (Left y)
else Just (Right (tail xs))
Your function however is quite verbose, you can make it more clear and compact as follows:
funct :: Int -> [Int] -> Maybe (Either Int [Int])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
Furthermore we can generalize it to:
funct :: Eq a => a -> [a] -> Maybe (Either a [a])
funct _ [] = Nothing
funct y (h:t) | h == y = Just (Left y)
| otherwise = Just (Right t)
Here Eq is a typeclass that specifies that there exists a function (==) :: a -> a -> Bool that we can use. Otherwise using == in the body of the function would not be possible.
Furthermore we use patterns in the head of every clause. [] is a pattern that describes the empty list. (h:t) on the other hand is a pattern describing a list containing at least one element: the head h, followed by a (possibly empty tail t).

Guards and where haskell

I have a very basic Haskell function.
It should prepend a tuple to list if not present returning it.
Added tuple needs to be edited before prepending.
I expect a function whose type is this:
Num t => (a, t) -> [(a, t)] -> [(a, t)]
Function is this:
update x lst
| hasElement x lst == True = addElement x lst
| otherwise = lst
where hasElement element list = not (null (filter ((==element).fst) list))
addElement a b = (fst a, (snd a) +1) : b
but I got an error when I try to load the module:
• Occurs check: cannot construct the infinite type: a ~ (a, t)
Expected type: [(a, t)]
Actual type: [((a, t), t)]
• In the second argument of ‘addElement’, namely ‘lst’
In the expression: addElement x lst
In an equation for ‘update’:
update x lst
| hasElement x lst == True = addElement x lst
| otherwise = lst
where
hasElement element list
= not (null (filter ((== element) . fst) list))
addElement a b = (fst a, (snd a) + 1) : b
• Relevant bindings include
lst :: [((a, t), t)] (bound at pip.hs:40:10)
x :: (a, t) (bound at pip.hs:40:8)
update :: (a, t) -> [((a, t), t)] -> [(a, t)]
(bound at pip.hs:40:1)
The addElement return type seems breaks all up since commenting it out makes the module work.
Question is: what's wrong?
Trying function alone seems working as I expect.
Thanks,
FB
The reason for that particular error is that element contains both a key and a value, but by (==element) . fst you try to compare only the key.
The best way to actually get only at the key is to pattern match it right in the function argument. Note that you don't really need the element variable at all, nor the other arguments to the local functions:
update (key,y) lst
| hasElement = addElement -- comparing `==True` is a no-op!
| otherwise = lst
where hasElement = not . null $ filter ((==key).fst) lst
addElement = (key, y+1) : b
I'd question though if this behaviour of addElement is really what you want: you're not updating the existing element with a given key, but adding a new element with the same key?
Also, the combination of not, null and filter is needlessly complicated. You can just use
hasElement = any ((==key).fst) lst
Finally, the signature Num a => ... is actually not strong enough: you're comparing keys with ==. That only works if the keys have an Eq instance. So, this is the correct signature:
(Eq a, Num t) => (a, t) -> [(a, t)] -> [(a, t)]

Resources