Member Function in Haskell - list

Working on a small assignment for class, having a lot of trouble with Haskell. I am trying to make a recursive method for finding if an integer is part of a list or not. I know the gist, but am unable to get it working correctly with the haskell syntax. Check if the current list is empty, if so then False, then check if integer is equal to the head of the current list, if so, then True, then call member again with the same value you are searching for, and the tail of the list. What can I do to get this functioning properly.
Currently this is what I have:
member ::Int -> [Int] -> Bool
member x y
if y [] then False
else if x == head y then True
else member x tail y
I have also tried using
member :: (Eq x) => x -> [x] -> Bool
as the beginning line, and also a much simplier :
let member x y = if null y then False
else if x == head y then True
else member x tail y
Any help would be appreciated.

with pattern matching you can write it more clearly
member :: (Eq a) => a -> [a] -> Bool
member x [] = False
member x (y:ys) | x==y = True
| otherwise = member x ys

element _ [] = False
element e (x:xs) = e == x || e `element` xs
-- OR
element e xs = if xs == [] then False
else if e == head xs then True
else e `element` tail xs
-- OR
element e xs = xs /= [] && (e == head xs || e `element` tail xs)
-- x `op` y = op x y
-- If you're feeling cheeky
element = elem
Your syntax appears very confused, but your logic makes sense, so here's a bucket list of things to remember:
Functions can be defined by multiple equations. Equations are checked top to bottom. That means using =.
Pattern matches are not equality tests. A pattern match breaks a value into its constituents if it matches and fails otherwise. An equality test x == y returns a Bool about the equality of x and y.
Pattern matching is used for flow control via...
a case statement, like
case xs of {
[] -> ...
x:xs' -> ...
}
Multiple equations, like
element _ [] = ...
element e (x:xs) = ...
Note that you can ignore a value in a pattern with _. With multiple equations of a function with multiple arguments, you're really pattern matching on all the arguments at once.
Bools are used for flow control via if _ then _ else _:
if xs == [] then False
else True
which is really just
case x == y of {
True -> False
False -> True
}
and Bools can use the ordinary operators (&&) (infixr 3) and (||) (infixr 2)
The difference is especially nefarious on lists. instance Eq a => Eq [a], so in order to use == on lists, you need to know that the elements of the lists can be compared for equality, too. This is true even when you're just checking (== []). [] == [] actually causes an error, because the compiler cannot tell what type the elements are. Here it doesn't matter, but if you say, e.g. nonEmpty xs = xs /= [], you'll get nonEmpty :: Eq a => [a] -> Bool instead of nonEmpty :: [a] -> Bool, so nonEmpty [not] gives a type error when it should be True.
Function application has the highest precedence, and is left-associative:
element x xs reads as ((element x) xs)
element x tail xs reads as (((element x) tail) xs), which doesn't make sense here
f $ x = f x, but it's infixr 0, which means it basically reverses the rules and acts like a big set of parentheses around its right argument
element x $ tail xs reads as ((element x) (tail xs)), which works
Infix functions always have lower precedence than prefix application:
x `element` tail xs means ((element x) (tail xs)), too
let decls in expr is an expression. decls is only in scope inside expr, and the entire thing evaluates to whatever expr evaluates to. It makes no sense on the top level.
Haskell uses indentation to structure code, like Python. Reference

Related

Haskell isMember function error

isMember:: a -> [a] -> Bool
isMember y [] = False
isMember y (x:xs) =
if y == x then
True
else
isMember y xs
Trying to create a function that will identify whether something is a member of a list. For example:
isMember 6 [1,2,3,4,5,6]
>True
However I keep getting a complier error stating 'no instance for (Eq a) arising from the use of '=='
Help would be appreciated (I'm new to Haskell & Recursion in functional languages so explain like I'm five.)
you are almost there
isMember :: Eq a => a -> [a] -> Bool
isMember _ [] = False
isMember y (x:xs) =
if y == x then True else isMember y xs
What the compiler tells you that you promised to accept any type of list members - but later you use the function == which is not available for all types (for example functions).
By adding Eq a => you say I accept all input which have an equals method.
Some additional notes
You can (re)write the last line as
isMember y (x:xs) = (y == x) || isMember y xs
which is equivalent to your implementation (thanks #chi for the comment).
What is nice about your version is that it is tail recursive.
Another point to note - the pattern:
return something for empty list case (isMember _ [] = False)
and iterate over the list with this value (isMember y (x:xs) = ...)
happens to turn up a lot and has been abstracted into the family of fold -functions (foldl, foldr ...). Putting it in your use case it looks like
isMember y xs = foldl False (\x b -> (x == y) || b) xs

Grouping consecutive duplicates in a list?

Very basic but I'm finding the problem frustrating. I'm trying to group consecutive elements of a list:
myList = [1,2,3,4,4,4,5]
becomes
myList = [[1],[2],[3],[4,4,4],[5]]
This is my attempt using foldr with an accumulator:
print $ foldr (\ el acc -> if el /= head (head acc) then el ++ (head acc) else acc) [['a']] myList
I don't understand why I'm getting the following error:
Couldn't match expected type ‘[a0]’ with actual type ‘Int’
In the expression: 'a'
In the expression: ['a']
In the second argument of ‘foldr’, namely ‘[['a']]’
Any advice would be great!
Writing a fold on lists requires us to answer just two cases: [] (the empty list, or "nil") and x:xs (an element followed by a list, or "cons").
What is the answer when the list is empty? Lets say the answer is also an empty list. Therefore:
nilCase = []
What is the answer when the list is not empty? It depends on what we have already accumulated. Lets say we have already accumulated a group. We know that groups are non-empty.
consCase x ((g11:_):gs)
If x == g11 then we add it to the group. Otherwise we begin a new group. Therefore:
consCase x ggs#(g1#(g11:_):gs)
| x == g11 = (x:g1):gs
| otherwise = [x]:ggs
What if we have not accumulated any groups yet? Then we just create a new group.
consCase x [] = [[x]]
We can consolidate the three cases down to two:
consCase x ggs
| g1#(g11:_):gs <- ggs, x == g11 = (x:g1):gs
| otherwise = [x]:ggs
Then the desired fold is simply:
foldr consCase nilCase
Using foldr, it should be:
group :: (Eq a) => [a] -> [[a]]
group = foldr (\x acc -> if head acc == [] || head (head acc) == x then (x:head acc) : tail acc else [x] : acc) [[]]
The type of your case case is [[Char]], you are attempting to build a value of type [[Int]]. Our base case should be an empty list, and we'll add list elements in each step.
Let's look at the anonymous function you're written next. Note that we'll fail due to type based on your current if within the accumulator (they must return values of the same type, and the same type as the accumulator. It'll be better, and cleaner, if we pattern match the accumulator and apply the function differently in each case:
func :: Eq a => [a] -> [[a]]
func = foldr f []
where f x [] = undefined
f x (b#(b1:_):bs)
| x == b1 = undefined
| otherwise = undefined
When we encounter the base case, we should just add the our element wrapped in a list:
f x [] = [[x]]
Next, we'll deal with the non-empty list. If x is equal to the next head of the head of the list, we should add it to that list. Otherwise, we shou
f x (b#(b1:_):bs)
| == b1 = (x:b):bs
| = [x]:b:bs
Putting this together, we have:
func :: Eq a => [a] -> [[a]]
func = foldr f []
where f x [] = [[x]]
f x (b#(b1:_):bs)
| x == b1 = (x:b):bs
| otherwise = [x]:b:bs
Having broken the problem down, it's much easier to rewrite this more compactly with a lambda function. Notice that the head [[]] is just [], so we can handle the empty list case and the equality case as one action. Thus, we can rewrite:
func :: (Eq a) => [a] -> [[a]]
func = foldr (\x (b:bs) -> if b == [] || x == head b then (x:b):bs else [x]:b:bs) [[]]
However, this solution ends up requiring the use of head since we must pattern match all versions of the accumulator.

Why right folding can process infinite list in Haskell?

For an infinite list, there's no "last" element of it. So how could foldr work with it?
I've this code snippet from the Haskell book:
(&&)::Bool->Bool->Bool
True && x = x
False && _ = False
and' :: [Bool]->Bool
and' xs=foldr (Main.&&) True xs
Then in Prelude load this hs file and run:
*Main> and' (repeat False)
False
It works as expected, but I don't understand:
The definition of the (&&) receives boolean on the left of it,
but we apply True && x = x while the variable x is in its right side.
Isn't it strange?
Why foldr stops when (&&) returns False?
In my understanding foldr will loop through the list from tail till head.
Is there any internal "break" mechanism?
foldr starts from the last element of a list, but infinite list has no end.
How does foldr begin to work?
You need to familiarize with the syntax a bit.
In Haskell, a function definition goes like this:
this = that
and, basically, it means: When you see this it means that. In fact
True && x
is the same as x, and
False && x
is False, that is why we can write the definitions as in your example.
For your second question: it is not the case that foldr "stops". It is the && operator who does not evaluate its right operand, when the left one is False.
For your 3rd question: no, foldr does not start from the last element of a list. Please have a look at the definition of foldr:
foldr f z [] = z
foldr f z (x:xs) = x `f` foldr f z xs
Now suppose
foldr (&&) True (False:xs)
it evaluates to
False && foldr (&&) True xs
And since
False && _
is False, the result is False
Let's repeat your definitions and add a couple more:
(&&)::Bool->Bool->Bool
True && x = x
False && _ = False
and :: [Bool]->Bool
and xs = foldr (&&) True xs
repeat :: a -> [a]
repeat a = a : repeat a
foldr :: (a -> r -> r) -> r -> [a] -> r
foldr _ z [] = z
foldr f z (a:as) = f a (foldr f z as)
Now, we can prove this by evaluating it manually, taking care to do it "lazily" (outermost applications first, and evaluating only enough to resolve the outermost data constructors):
and (repeat False)
= foldr (&&) True (repeat False) -- definition of `and`
= foldr (&&) True (False : repeat False) -- definition of `repeat`
= False && foldr (&&) True (repeat False) -- `foldr`, second equation
= False -- `&&`, second equation
The key is that the second equation of the definition of && discards its second argument:
False && _ = False
This means, in runtime terms, that we never force foldr's recursive call at a step where we encounter False.
Another way to look at it is to contemplate foldr's second equation, and what it means when we have lazy evaluation:
foldr f z (a:as) = f a (foldr f z as)
Since the recursive call to foldr happens as an argument to f, this means that, at runtime, the function f decides whether the value of its second argument is necessary or not, and so chooses at each step of the fold whether to recurse down the list or not. And this "decision" process proceeds from left to right.
In my understanding foldr will loop through the list from tail till head. Is there any internal "break" mechanism?
Strictly speaking, in a pure functional language there is no intrinsic notion of evaluation order. Expressions may be evaluated in any order that's consistent with their data dependencies.
What you've said here is a common misunderstanding that people who've learned foldr from impure, eager languages carry over to Haskell. In an eager language that's a useful rule of thumb, but in Haskell, with purity lazy evaluation, that rule will only confuse you. Often the opposite rule of thumb is useful when programming Haskell: foldr will visit the list elements from left to right, and at each step its f argument function gets to decide whether the rest of the list is necessary.
The extreme example of this is to implement a function to get the head of a list using foldr:
-- | Return `Just` the first element of the list, or `Nothing` if the
-- list is empty.
safeHead :: [a] -> Maybe a
safeHead = foldr (\a _ -> Just a) Nothing
So for example:
safeHead [1..]
= foldr (\a _ -> Just a) Nothing [1..]
= foldr (\a _ -> Just a) Nothing (1:[2..])
= (\a _ -> Just a) 1 (foldr (\a _ -> Just a) Nothing [2..])
= Just 1

Function that removes element if it exists but adds it of it does not

I'm looking for a cleaner way to write a function that adds an element to a list if the list does not contain it. Or otherwise removes it if the list does contain it, I'm using an if clause now and the function is working.
But I'm trying to find a more haskell-ish way to right this.
This is my code:
removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd elem list = if (List.elem elem list)
then (filter(\x -> x /= elem) list)
else (elem:list)
Note: a small ambiguity in your question is what to do when x already occurs multiple times in the original list. I assumed this won't happen and in case it does, only the first occurrence is removed. Meaning that removeElemOrAdd 2 [4,2,5,2,7] will result in [4,5,2,7]. Furthermore it is unspecified where the item should be added. Because it has some advantages, I've opted to do this at the end of the list.
An implementation without using any library methods is the following:
removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd x (y:ys) | x == y = ys
| otherwise = y : removeElemOrAdd x ys
removeElemOrAdd x _ = [x]
Or a shorter version:
removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd x = reoa
where reoa (y:ys) | x == y = ys
| otherwise = y : reoa ys
reoa _ = [x]
or an equivalent implementation (see discussion below):
removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd x = reoa
where reoa (y:ys) | x == y = ys
| otherwise = y : reoa ys
reoa [] = [x]
The function works as follows: in case we are talking about a list with at least one item (y:ys), we compare x with y and if they are equal, we return ys: in that case we have removed the element and we are done.
Now in case the two are not equal, we return a list construction (:) with y in the head since we need to retain y and in the tail, we will do a recursive call removeElemOrAdd with x and ys. Indeed: it is possible that there is an x somewhere in the tail ys to remove, and furthermore we still need to add x to the list if it does not occur.
That clause will loop recursively through the list. From the moment it finds an y such that x == y it will remove that y. It is however possible that we reach the end of the list, and still have not found the element. In that case we will call the final clause. Here we know the list is empty (we could have written removeElemOrAdd x []) but to make the function definition syntactically total, I have opted to use an underscore. We can only reach this state if we have failed to find x in the list, so then we add it to the tail of the list by returning [x].
An advantage of this approach over using the if-then-else is that this does all tasks at once (checking, removing and adding) making it more efficient.
Another advantage is that this can run on an "infinite" list (like for instance the list of prime numbers). The list is evaluated lazily, so if you want to take the first three items, this function will only check the equality of the first three items.
I like the other approaches, but don't like that they behave differently than the specification. So here is an approach that:
Like the original, deletes all copies, if there are any, AND
like the original, inserts the new value at the beginning, if necessary, BUT
unlike the original, uses a clever trick based on the ideas of beautiful folding (and follow-up developments) to make only one pass through the data.
The basic idea is that we will have a single value which tracks both whether all values so far have been a mismatch as well as the resulting filtered list. The injectNE operation will perform this operation for a single element of the list, and we will then use foldMap to expand from one element to the whole input list.
import Data.Monoid
injectNE :: Eq a => a -> a -> (All, [a])
injectNE old new = (All ne, [new | ne]) where
ne = old /= new
removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd x xs = case foldMap (injectNE x) xs of
(All nex, noxs) -> [x | nex] ++ noxs
In the final pattern, you should read nex as "no element was equal to x", and noxs as "the list without any copies of x" (get it? "no xs"? ba-dum-tsh).
It is slightly unfortunate that the spec was written the way it was, though: in particular, one of the selling points of beautiful folding is that its resulting one-pass folds can be friendlier to the garbage collector. But the spec makes that quite hard, because we must traverse the entire input list before deciding what the first element of the result list should be. We can improve the friendliness to the garbage collector significantly by relaxing point (2) above (but leaving (1) and (3)); and moreover the difference is merely swapping the arguments to (++), a nicely semantic diff to see in your revision history:
-- <snipped identical code>
removeElemOrAdd x xs = case ... of
... -> noxs ++ [x | nex]
I'd use a fold to remove all copies:
removeOrAdd x xs = foldr go (bool [x] []) xs False where
go y r found
| y == x = r True
| otherwise = y : r found
To remove just one, a paramorphism seems to be in order:
removeOrAdd x = para go [x] where
go y ys r
| y == x = ys
| otherwise = y : r

Haskell Function that Takes A Pair of Values and a List

My homework has been driving me up the wall. I am supposed to write a function called myRepl that takes a pair of values and a list and returns a new list such that each occurrence of the first value of the pair in the list is replaced with the second value.
Example:
ghci> myRepl (2,8) [1,2,3,4]
> [1,8,3,4].
So far I have something like this (but its very rough and not working well at all. I need help with the algorithm:
myRep1 (x,y) (z:zs) =
if null zs then []
else (if x == z then y : myRep1 zs
else myRep1 zs )
I don't know how to create a function that takes a pair of values and a list. I'm not sure what the proper syntax is for that, and I'm not sure how to go about the algorithm.
Any help would be appreciated.
How about something like:
repl (x,y) xs = map (\i -> if i==x then y else i) xs
Explanation
map is a function that takes a function, applies it to each value in the list, and combines all the return values of that function into a new list.
The \i -> notation is a shortcut for writing the full function definition:
-- Look at value i - if it's the same as x, replace it with y, else do nothing
replacerFunc x y i = if x == y then y else i
then we can rewrite the repl function:
repl (x, y) xs = map (replacerFunc x y) xs
I'm afraid the map function you just have to know - it is relatively easy to see how it works. See the docs:
http://www.haskell.org/hoogle/?hoogle=map
How to write this without map? Now, a good rule of thumb is to get the base case of the recursion out of the way first:
myRep1 _ [] = ???
Now you need a special case if the list element is the one you want to replace. I would recommend a guard for this, as it reads much better than if:
myRep1 (x,y) (z:zs)
| x == z = ???
| otherwise = ???
As this is home work, I left a few blanks for you to fill in :-)
myRepl :: Eq a => (a, a) -> [a] -> [a]
myRepl _ [] = []
myRepl (v, r) (x : xs) | x == v = r : myRepl (v, r) xs
| otherwise = x : myRepl (v, r) xs
Untupled arguments, pointfree, in terms of map:
replaceOccs :: Eq a => a -> a -> [a] -> [a]
replaceOccs v r = map (\ x -> if x == v then r else x)