Haskell Question on pattern matching - list

I'm trying to write a function that takes in a list and returns true if it is in sorted order and false if not:
So far what I have is:
myordered [] = True
myordered [x] = True
myordered list1
| (head list1) <= (head (tail list1)) = myordered(tail list1)
| otherwise = False
Based on our assignment, all head and tail operations should be written down as "x:xs" type syntax.
the translation I come up with for the section with a guard is:
myordered y:x:xs
| (y) <= (x) = myordered(xs)
| otherwise = False
Essentially this question boils down to:
How do you express the (head (tail list1)) in "x:xs" type syntax?
Cheers,
-Zigu

Your pattern is almost correct, you just need to surround it with parentheses:
myordered (y:x:xs)
Also note that there's no need to surround y and x with parentheses in y <= x.
Also there's a semantic mistake in your second version:
myordered(xs) here xs refers to the tail of tail, but you want the whole tail, so you should do myordered (x:xs) or alternatively:
myordered (y:xs#(x:_))
| y <= x = myordered xs
| otherwise = False
Which says: xs is the tail of that list, x is the head of that tail, and _ (which is ignored) is the tail of the tail.

How about another way to do this with the help of zipWith function available in Data.List
myordered xs= and $ zipWith (<=) xs (tail xs)
zipWith function takes two list and apply a function. Here it will return an array of boolean according to the condition .
and takes a list of boolean values and returns True only if all the values in the list are True

How about
isordered :: [Int] → Bool
isordered [] = True
isordered xs = foldl (&&) True $ zipWith (<=) xs $ tail xs
Oh, and just for fun:
isordered :: [Int] → Bool
isordered [] = True
isordered (x:xs) = (foldl comp (Just x) xs) /= Nothing
where comp (Just a) b = if a ≤ b then Just b else Nothing
comp Nothing _ = Nothing

Related

Determining if there are repeated elements in a list in Haskell

I'm trying to test lists for duplicates but when I compile and enter
repeated [1,2,3,4]
it outputs True. What's wrong?
belongs :: Eq a => a -> [a] -> Bool
belongs n [] = False
belongs n (x:xs) | n == x = True
| otherwise = belongs n xs
repeated :: [Integer] -> Bool
repeated [] = False
repeated (x:xs) | belongs x xs = True
| otherwise = belongs (head xs) xs
"belongs (head xs) xs" checks whether xs's head is within xs, which will always be true.
(Except when xs is empty, in which case your program will crash! "head" is a partial function, crashes with empty lists)
This would fix it (as pointed by #talex too, but I also suggest making it more general, there is no need to specialize it to Integer):
repeated :: Eq a => [a] -> Bool
repeated [] = False
repeated (x:xs) | belongs x xs = True
| otherwise = repeated xs
You want
repeated :: [Integer] -> Bool
repeated [] = False
repeated (x:xs) | belongs x xs = True
| otherwise = repeated xs

Member Function in Haskell

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

Haskell about recursion in list function

i'm tryin to create a function(i'm new in haskell) which Needs two lists and Returns one List. The List should have all of the Elements of the first list,who aren't in the second and all of the second List, who aren't in the first.
So: func [3,2,1,4] [2,5,1] should return [3,4,5]
I think my Code goes to the right direction, but somewhere in it is a big mistake.
func :: [Int] -> [Int] -> [Int]
func [] a = a
func a [] = a
func (x:xs) (y:ys) | elem x (y:ys) = filter (/=x) (y:ys)
| otherwise = func ys xs
Pretending not to have any experience with this domain of problems or be very familiar with the functions in base, I'll rephrase your problem statement to describe the operation we want and show you how I'd approach it:
The result of fun on two lists is: all of the Elements of the first
list,who aren't in the second and all of the second List, who aren't
in the first.
To begin expressing this in code, replace "is" with =:
func l1 l2 = (elementsOfFirstNotInSecond l1 l2) ++(elementsOfFirstNotInSecond l2 l1)
Now we need to implement elementsOfFirstNotInSecond, so let's start with words:
elementsOfFirstNotInSecond on two lists is: if l1 is the empty
list then the empty list, otherwise if the head of l1 (we'll call it
"x") is a member of l2 then x consed onto
elementsOfFirstNotInSecond of the tail of l1 and l2. Otherwise
(if x was not in l2) it's just elementsOfFirstNotInSecond of
the tail of l1 and l2
See if you can translate that to haskell, using not-yet-implemented functions (e.g. you might want to use (isAMemberOf :: Int -> [Int] -> Bool), and repeat the excercie.
Does output order matter?
If not, you could just use list difference (\\) from Data.List
Prelude > import Data.List
Prelude Data.List> as = [3,2,1,4]
Prelude Data.List> bs = [2,5,1]
Prelude Data.List> notinSec = as \\ bs
Prelude Data.List> notinFst = bs \\ as
Prelude Data.List> ans = notinSec ++ notinFst
Prelude Data.List> ans
[3,4,5]
Since you want recursion and are new with haskell,so solution(movin' in your direction) would be something like
func (x:xs) (y:ys) | elem x (y:ys) && (not (elem y (x:xs))) = func xs (filter (/=x) (y:ys))
| (not (elem x (y:ys))) && (elem y (x:xs)) = func (filter (/=y) (x:xs)) ys
| (elem x (y:ys)) && (elem y (x:xs)) = func (filter (/=y) (xs)) (filter (/=x) (ys))
| otherwise = x : y : (func xs ys)
But you can see how ugly and imbecile this is at later stages in your learning path.
I suggest you go with simpler and concise alternative.

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.

Haskell - Checking if all list elements are unique

I need to compare if all elements of a given list are unique.
(For the record I am doing so for academic purposes.)
Here is what I have thus far:
allDifferent :: (Eq a) => [a] -> Bool
allDifferent list = case list of
[] -> True
(x:xs) -> if x `elem` xs then False else allDifferent xs
Which works wonderfully!
Now, when I try to do it like this...
allDifferent2 :: (Eq a) => [a] -> Bool
allDifferent2 list
| null list = True
| (head list) `elem` (tail list) || allDifferent2 (tail list) = False
| otherwise
It just doesn't work as intended.
I get the following output from GHCi:
*Main> allDifferent2 [1..4]
False
*Main> allDifferent2 [1..5]
True
*Main> allDifferent2 [1..6]
False
*Main> allDifferent2 [1..7]
True
i.e. For every list with an even amount of elements it outputs False and for an odd amount of elements, True.
What am I missing?
Would anyone care to shine some light?
An alternative exploiting notElem:
allDifferent :: (Eq a) => [a] -> Bool
allDifferent list = case list of
[] -> True
(x:xs) -> x `notElem` xs && allDifferent xs
Minor variant, using pattern matching directly in the equations:
allDifferent :: (Eq a) => [a] -> Bool
allDifferent [] = True
allDifferent (x:xs) = x `notElem` xs && allDifferent xs
I tend to stay away from partial functions like head,tail, so the variants based on guards look worse to me.
I would do this differently. Recursion + elem is O(n²). Alternatively you can first sort the list, and then compare elements pairwise. This way the sorting is O(n⋅log n), and the traversal O(n). So overall O(n⋅log n):
import Data.List
allDifferent :: (Ord a, Eq a) => [a] -> Bool
allDifferent = comparePairwise.sort
comparePairwise :: Eq a => [a] -> Bool
comparePairwise [] = True
comparePairwise [_] = True
comparePairwise (x:y:xs)
| x == y = False
| otherwise = comparePairwise (y : xs)
You can rely on library functions: allDifferent xs = nub xs == xs.
Or, written in point-free notation: allDifferent = uncurry (==) . (nub &&& id).
Using Data.Discrimination.nub, this happens in O(n) time.
The simplest reasonable idiomatic approach I can think of is
allDifferent :: Ord a => [a] -> Bool
allDifferent = pairwiseDifferent . sort
pairwiseDifferent :: Eq a => [a] -> Bool
pairwiseDifferent xs = and $ zipWith (/=) xs (drop 1 xs)
For fun with folds,
import Data.Maybe
pairwiseDifferent xs = foldr go (const True) xs Nothing
where
go x k Nothing = k (Just x)
go x k (Just prev) = x /= prev && k (Just x)
Another option is to use a Set (some of the strictness annotations may not actually be necessary):
import qualified Data.Set as S
allDifferent xs = foldr go (\s -> s `seq` True) xs S.empty
where
go x k s
| S.member x s = False
| otherwise = k $! S.insert x s
Try this:
allDifferent2::(Eq a) => [a] -> Bool
allDifferent2 list
| list == [] = True
| (head list) `elem` (tail list) = False
| otherwise = allDifferent2(tail list)
If the list is [] you should return True (As #bheklilr said :) )
If the list isn't null, you can verify if the first element is in the tail of the list. If it is, return False. Okay.
But when you say "if it is in the tail of the list OR allDifferent2 (tail list)" you are killing your function. "If all the elements are different in this list, return FALSE", and that isn't what you want.
EDIT: Yeah, it will #Luis. I fixed that by putting that "otherwise" there. When I put the guard before the allDifferent2(tail list) it checked if this function returned True. Thus it would work for [1, 1, 2] (my test-case) but not for [1, 2, 2] (similar to your case).
Sort the list, group runs of equal elements together, and check if all groups have exactly one element.
import Data.List (group, sort)
pairwiseDistinct :: Ord a => [a] -> Bool
pairwiseDistinct xs = all (\ys -> null (tail ys)) (group (sort xs))
Point-free version:
pairwiseDistinct = all (null . tail) . group . sort
This assumes that for any two elements x and y, x == y if and only if compare x y == EQ.
tail is fine here because none of the groups will ever be empty, but you can substitute drop 1 if you're averse to partial functions.
allDifferent [] = True
allDifferent (h:t) =
let (e,(l,r)) = segment h t
in e && allDifferent l && allDifferent r
segment p [] = (True,([],[])))
segment p (h:s)
| p > h = let (e,(l,r)) = segment p s in (e,(l,h:r))
| p < h = let (e,(l,r)) = segment p s in (e,(h:l,r))
| otherwise = (False,([],[])))
As you can see the structure of this solution is very similar to quickSort.
It shares as an intermediate data structure a binary tree and for that reason, the time complexity is extremely similar.