Struggling with Haskell syntax with if's and else's - if-statement

I'm struggling with the syntax of Haskell and am getting receiving "error: parse error on input ‘if’" when I try to compile my script with GHCI. The aim of my code is to return the minimum and maximum of an unordered list. It does this recursively by splitting the list in half and finding the minimum and maximum of each half. If the list has only one element it simply returns that that element is both the maximum and the minimum, if the list has two elements it does a simple comparison to find the minimum and maximum. Here is my code, the "splitlist" function was taken from an online resource:
splitlist :: [a] -> ([a], [a])
splitlist xs = splitAt ((length xs + 1) `div` 2) xs
minMax :: [Int] -> [Int]
minMax x
if length x == 1 then
[x, x]
else if length x == 2 then
if (head x > tail x) then
[tail x, head x]
else
[head x, tail x]
else
listOfLists = splitlist x
list1 = listOfLists!!0
list2 = listOfLists!!1
minMax1 = minMax list1
minMax2 = minMax list2
if (minMax1!!0 < minMax2!!0) then
min = minMax1!!0
else
min = minMax2!!0
if (minMax!!1 > minMax2!!1) then
max = minMax1!!1
else
max = minMax2!!1
[min, max]
I am also suspicious that I am not attempting to do this in a way that Haskell was meant for, I'm a beginner and still accidentally treat it like python quite a lot. Ideally if someone could tell me what I'm doing wrong with my method and then show me a method more in line with Haskell's design principles I would be very appreciative.

There are several things in your function that isn't valid Haskell syntax. You are missing a =, and you are trying to declare variables in a way Haskell doesn't allow.
I tried to rearrange your code to be correct and here is what I got:
splitlist :: [a] -> ([a], [a])
splitlist xs = splitAt ((length xs + 1) `div` 2) xs
minMax :: [Int] -> [Int]
minMax x = if length x == 1 then
[head x, head x]
else if length x == 2 then
if (head x > (head $ tail x)) then
[(head $ tail x), head x]
else
[head x, (head $ tail x)]
else [if (minMax1!!0 < minMax2!!0) then minMax1!!0 else minMax2!!0,
if (minMax1!!1 > minMax2!!1) then minMax1!!1 else minMax2!!1]
where
listOfLists = splitlist x
list1 = fst listOfLists
list2 = snd listOfLists
minMax1 = minMax list1
minMax2 = minMax list2
It looks like your algorithm works as expected! It was a little tricky because this isn't usually the way most people tend to write Haskell methods.
Here is a different implementation that might be useful for comparison:
minMax :: [Int] -> [Int]
minMax [] = []
minMax (x:xs) = minMax' x x xs
where
minMax' a b [] = [a, b]
minMax' a b (x:xs) = minMax' (min a x) (max b x) xs

Related

List to tuple counting values repeated and the list inside the tuple - Haskell

im learning functional programming with Haskell and i have this exercise where i have something like [a], z, with [a] any kind of list and z the element that im gonna erase inside [a]. This problem it's kinda easy to solve (even for a newbie like me in Haskell) but I am having troubles with the way I need to print the output.
I need to create a tuple where the first element is the list without any z element and the number of times that it found z inside of a. Couple examples:
Input: [2,3,4,2,2] 2
Output: ([3,4],3)
Input: [1,1,1,1] 1
Output: ([],4)
Input: [1,2,3,4] 5
Output: ([1,2,3,4],0)
So far i've done something like this but I don't know how to keep going:
ex3 :: (Eq a, Num a) => [a] -> a -> ([a],Int)
ex3 [] _ = ([],0)
ex3 (x:xs) z | x == z = (xs,1) -- this line is wrong, but idk how to fix it
| otherwise = ([0],0) -- same here
I've done both problems individually (deleting z elements and counting how many times z is in [a]. Looks like this:
a) Deleting z elements:
ex3a :: (Eq a) => [a] -> a -> [a]
ex3a [] _ = []
ex3a (x:xs) z | x == z = ex3a xs z
| otherwise = x : ex3a xs z
b) Counting how many times z is in [a]:
ex3b :: (Eq a) => [a] -> a -> Int
ex3b [] _ = 0
ex3b (x:xs) z | x == z = 1 + ex3b xs z
| otherwise = ex3b xs z
Usually it helps to think of functions like in mathematics you think about inductive definitions. For example the first line of your function can read like:
"The ex3 of an empty list, and any element is a tuple containing the empty list and zero"
ex3 [] _ = ([], 0)
For non-empty lists of course the problem is a bit harder. Like in your code, there are basically two cases here.
"The ex3 of a non-empty list and an element z where the head of the list is not equal to z is the same as the ex3 of the tail of the list, but prepended with the head of that list", so we can write it like:
ex3 [] _ = ([], 0)
ex3 (x:xs) z | x /= z = (x:t, n)
| otherwise = ...
where (t, n) = ex3 xs z
So here we make a recursive call to ex3 with the tail of the list xs, and we obtain the result tuple (t, n), so t contains the "erased" tail, and n the number of times we removed the element, and in case x /= z, then we can return (x:t, n), since the number of removals does not change, but we have to prepend x to the list.
"The ex3 of a non-empty list and an element z where the head of the list is equal to z is the same as the ex3 of the tail of the list but with an incremented count", so:
ex3 :: (Eq a, Num n) => [a] -> a -> ([a], n)
ex3 [] _ = ([], 0)
ex3 (x:xs) z | x /= z = (x:t, n)
| otherwise = (t, n+1)
where (t, n) = ex3 xs z
We then obtain the expected results:
Prelude> ex3 [2,3,4,2,2] 2
([3,4],3)
Prelude> ex3 [1,1,1,1] 1
([],4)
Prelude> ex3 [1,2,3,4] 5
([1,2,3,4],0)
Just for fun, this is how I would implement that function:
import Data.Foldable
import Data.Monoid
ex3 :: Eq a => [a] -> a -> ([a], Int)
ex3 haystack needle = getSum <$> foldMap inject haystack where
inject hay | hay == needle = ([], 1)
| otherwise = ([hay], 0)
What I like about this is that the recursion pattern is immediately obvious -- at least to those familiar with Haskell's standard library -- without careful scrutiny (because it is just a call to foldMap).
The partition function consumes a predicate and a list; it produces a pair of lists whose first element satisfies the predicate, the second doesn't.
import Data.List (partition)
ex4 :: Eq a => [a] -> a -> ([a], Int)
ex4 xs x = length <$> partition (/= x) xs

haskell: how to get list of numbers which are higher then their neighbours in a starting list

I am trying to learn Haskell and I want to solve one task. I have a list of Integers and I need to add them to another list if they are bigger then both of their neighbors. For Example:
I have a starting list of [0,1,5,2,3,7,8,4] and I need to print out a list which is [5, 8]
This is the code I came up but it returns an empty list:
largest :: [Integer]->[Integer]
largest n
| head n > head (tail n) = head n : largest (tail n)
| otherwise = largest (tail n)
I would solve this as outlined by Thomas M. DuBuisson. Since we want the ends of the list to "count", we'll add negative infinities to each end before creating triples. The monoid-extras package provides a suitable type for this.
import Data.Monoid.Inf
pad :: [a] -> [NegInf a]
pad xs = [negInfty] ++ map negFinite xs ++ [negInfty]
triples :: [a] -> [(a, a, a)]
triples (x:rest#(y:z:_)) = (x,y,z) : triples rest
triples _ = []
isBig :: Ord a => (a,a,a) -> Bool
isBig (x,y,z) = y > x && y > z
scnd :: (a, b, c) -> b
scnd (a, b, c) = b
finites :: [Inf p a] -> [a]
finites xs = [x | Finite x <- xs]
largest :: Ord a => [a] -> [a]
largest = id
. finites
. map scnd
. filter isBig
. triples
. pad
It seems to be working appropriately; in ghci:
> largest [0,1,5,2,3,7,8,4]
[5,8]
> largest [10,1,10]
[10,10]
> largest [3]
[3]
> largest []
[]
You might also consider merging finites, map scnd, and filter isBig in a single list comprehension (then eliminating the definitions of finites, scnd, and isBig):
largest :: Ord a => [a] -> [a]
largest xs = [x | (a, b#(Finite x), c) <- triples (pad xs), a < b, c < b]
But I like the decomposed version better; the finites, scnd, and isBig functions may turn out to be useful elsewhere in your development, especially if you plan to build a few variants of this for different needs.
One thing you might try is lookahead. (Thomas M. DuBuisson suggested a different one that will also work if you handle the final one or two elements correctly.) Since it sounds like this is a problem you want to solve on your own as a learning exercise, I’ll write a skeleton that you can take as a starting-point if you want:
largest :: [Integer] -> [Integer]
largest [] = _
largest [x] = _ -- What should this return?
largest [x1,x2] | x1 > x2 = _
| x1 < x2 = _
| otherwise = _
largest [x1,x2,x3] | x2 > x1 && x2 > x3 = _
| x3 > x2 = _
| otherwise = _
largest (x1:x2:x3:xs) | x2 > x1 && x2 > x3 = _
| otherwise = _
We need the special case of [x1,x2,x3] in addition to (x1:x2:x3:[]) because, according to the clarification in your comment, largest [3,3,2] should return []. but largest [3,2] should return [3]. Therefore, the final three elements require special handling and cannot simply recurse on the final two.
If you also want the result to include the head of the list if it is greater than the second element, you’d make this a helper function and your largest would be something like largest (x1:x2:xs) = (if x1>x2 then [x1] else []) ++ largest' (x1:x2:xs). That is, you want some special handling for the first elements of the original list, which you don’t want to apply to all the sublists when you recurse.
As suggested in the comments, one approach would be to first group the list into tuples of length 3 using Preludes zip3 and tail:
*Main> let xs = [0,1,5,2,3,7,8,4]
*Main> zip3 xs (tail xs) (tail (tail xs))
[(0,1,5),(1,5,2),(5,2,3),(2,3,7),(3,7,8),(7,8,4)]
Which is of type: [a] -> [b] -> [c] -> [(a, b, c)] and [a] -> [a] respectively.
Next you need to find a way to filter out the tuples where the middle element is bigger than the first and last element. One way would be to use Preludes filter function:
*Main> let xs = [(0,1,5),(1,5,2),(5,2,3),(2,3,7),(3,7,8),(7,8,4)]
*Main> filter (\(a, b, c) -> b > a && b > c) xs
[(1,5,2),(7,8,4)]
Which is of type: (a -> Bool) -> [a] -> [a]. This filters out elements of a list based on a Boolean returned from the predicate passed.
Now for the final part, you need to extract the middle element from the filtered tuples above. You can do this easily with Preludes map function:
*Main> let xs = [(1,5,2),(7,8,4)]
*Main> map (\(_, x, _) -> x) xs
[5,8]
Which is of type: (a -> b) -> [a] -> [b]. This function maps elements from a list of type a to b.
The above code stitched together would look like this:
largest :: (Ord a) => [a] -> [a]
largest xs = map (\(_, x, _) -> x) $ filter (\(a, b, c) -> b > a && b > c) $ zip3 xs (tail xs) (tail (tail xs))
Note here I used typeclass Ord, since the above code needs to compare with > and <. It's fine to keep it as Integer here though.

How to recursively multiply all elements of a list with itself to create a matrix? OCaml

I need to create a weight matrix essentially by multiplying all the elements of a list with themselves.
for example if my list is [1;-1;1;-1], the resulting matrix would be
[[0;-1;1;-1],
[-1;0;-1;1],
[1;-1;0;-1],
[-1;1;-1;0]]
(diagonal is filled with 0's because a node shouldn't be able to lead to itself)
This would be a piece of cake, but it has to be done recursively, with the following constraints:
only List.hd, List.tl and List.nth can be used, and as a parameter, I can only pass in the list:
let rec listMatrix = fun(myList)->...
Is there any way to do this? Or should I just try to find some fundamentally different way to solve this problem?
Also, only functional approach is allowed, no global variables.
One way to do it recursively is as follows:
let l = [1;-1;1;-1];;
let rec index xs =
let idx xs i = match xs with
[] -> []
| (x::xss) -> (i,x) :: idx xss (i+1)
in idx xs 0
fst (x,y) = x
snd (x,y) = y
let rec mult xs ys = match xs with
[] -> []
| (x::xss) -> (List.map (fun y->if (fst x == fst y) then 0 else (snd y*snd x)) ys) :: (mult xss ys)
let mult0 xs = mult (index xs) (index xs)
What the code does is, as asked, multiplying a vector with itself. The vector is indexed with numbers in order to handle diagonal elements specially.
The output is:
# mult0 l;;
- : int list list =
[[0; -1; 1; -1]; [-1; 0; -1; 1]; [1; -1; 0; -1]; [-1; 1; -1; 0]]

Haskell: Splitting a list into 2 at index k

I'm pretty new to Haskell, and I'm having a little trouble. I'm trying to implement a function that takes a list, and an int. the int is supposed to be the index k at which the list is split into a pair of lists. The first one containing the first k elements of the list, and the second from k+1 to the last element. Here's what I have so far:
split :: [a] -> Int -> ([a], [a])
split [] k = error "Empty list!"
split (x:[]) k = ([x],[])
split xs k | k >= (length xs) = error "Number out of range!"
| k < 0 = error "Number out of range!"
I can't actually figure out how to do the split. Any help would be appreciated.
First of all, note that the function you are trying to construct is already in the standard library, in the Prelude - it is called splitAt. Now, directly looking at its definition is confusing, as there are two algorithms, one which doesn't use the standard recursive structure at all -splitAt n xs = (take n xs, drop n xs) - and one that is hand-optimized making it ugly. The former makes more intuitive sense, as you are simply taking a prefix and a suffix and putting them in a pair. However, the latter teaches more, and has this overall structure:
splitAt :: Int -> [a] -> ([a], [a])
splitAt 0 xs = ([], xs)
splitAt _ [] = ([], [])
splitAt n (x:xs) = (x:xs', xs'')
where
(xs', xs'') = splitAt (n - 1) xs
The basic idea is that if a list is made up of a head and a tail (it is of the form x:xs), then the list going from index k+1 onwards will be the same as the list going from k onwards once you remove the first element - drop (k + 1) (x : xs) == drop k xs. To construct the prefix, you similarly remove the first element, take a smaller prefix, and stick the element back on - take (k + 1) (x : xs) == x : take k xs.
What about this:
splitAt' = \n -> \xs -> (take n xs, drop n xs)
Some tests:
> splitAt' 3 [1..10]
> ([1,2,3],[4,5,6,7,8,9,10])
> splitAt' 0 [1..10]
> ([],[1,2,3,4,5,6,7,8,9,10])
> splitAt' 3 []
> ([],[])
> splitAt' 11 [1..10]
> ([1,2,3,4,5,6,7,8,9,10],[])
> splitAt' 2 "haskell"
> ("ha","skell")
Basically, you need some way of passing along partial progress as you recurse through the list. I used a second function that takes an accumulator parameter; it is called from split and then calls itself recursively. There are almost certainly better ways..
EDIT: removed all the length checks., but I believe the use of ++ means it's still O(n^2).
split xs k | k < 0 = error "Number out of range!"
split xs k = ssplit [] xs k
ssplit p xs 0 = (p, xs)
ssplit p (x:xs) k = ssplit (p++[x]) xs (k-1)
ssplit p [] k = error "Number out of range!"
to get the behavior in the original post or
ssplit p [] k = (p,[])
To get the more forgiving behavior of the standard splitAt function.
A common trick for getting rid of quadratic behavior in building a list is to build it up backwards, then reverse it, modifying Mark Reed's solution:
split xs k | k < 0 = error "Number out of range!"
split xs k = (reverse a, b)
where
(a,b) = ssplit [] xs k
ssplit p xs 0 = (p, xs)
ssplit p (x:xs) k = ssplit (x:p) xs (k-1)
ssplit p [] k = error "Number out of range!"
The error check in ssplit is fine since won't get checked (one of the earlier patterns will match) unless there is an actual error.
In practice you might want to add a few strictness annotations to ssplit to manage stack growth, but that's a further refinement.
See splitAt in the prelude:
ghci> :t flip splitAt
flip splitAt :: [a] -> Int -> ([a], [a])
ghci> flip splitAt ['a'..'j'] 5
("abcde","fghij")

haskell list and functional

This is homework that has been driving crazy for the last couple of days.
I got a list that I am applying a function to - pushing each element to the right if the element next to it is smaller then the previous one.
My function to pass over the list once and sort the head of the list:
sortEm lis#(x:y:xs) = if x > y then y: sortEm (x:xs) else lis
sortEm [x] = [x]
sortEm [] = []
myList (x:y:xs) = if x > y then sortEm lis else x:myList(y:xs)
myList [] = []
myList [x] = [x]
But my problem is that once that sortem has finished it returns either an empty list or a list containing one element, how would i design this the functional way?
I was thinking about foldl and some haskell magic to go along with that but currently I am stuck.
Thanks in advance
First of, your sortEm function name is misleading, it doesn't sort its argument list but inserts its head element into its tail. As it happens, there is an insert function already in Data.List module that inserts its first argument into the 2nd, so there's an equivalency
sortEm (x:xs) === Data.List.insert x xs
Now, inserting an item will only get you a sorted list back if you're inserting it into a list that is already sorted. Since empty list is sorted, that's what myList function does that you got in dave4420's answer. That is an "insertion" sort, progressively inserting elements of list into an auxiliary list, initially empty. And that's what the 2nd function does that you got in dave4420 answer:
insertionSort xs = foldr Data.List.insert [] xs
This does "apply sortem" i.e. inserts, "each element" only once. For a list [a,b,c,...,z] it's equivalent to
insert a (insert b (insert c (... (insert z []) ...)))
What you probably meant in your comment, i.e. comparing (and possibly swapping) two neighboring elements "only once", is known as bubble sort. Of course making only one pass through the list won't get it sorted, in a general case:
bubbleOnce xs = foldr g [] xs where
g x [] = [x]
g x xs#(y:ys) | x>y = y:x:ys -- swap x and y in the output
| otherwise = x:xs -- keep x before y in the output
Now, bubbleOnce [4,2,6,1,8] ==> [1,4,2,6,8]. The value that you expected, [2,4,1,6,8], would result from applying the folding function g in an opposite direction, from the left to the right. But that's much less natural to do here with Haskell lists:
bubbleOnce' [] = []
bubbleOnce' (x:xs) = let (z,h)=foldl g (x,id) xs in (h [z]) where
g (x,f) y | x>y = (x, f.(y:)) -- swap x and y in the output
| otherwise = (y, f.(x:)) -- keep x before y in the output
(edit:) see jimmyt's answer for the equivalent, but simple and nice version using straightforward recursion. It is also lazier (less strict) than both the fodlr and foldl versions here.
myList [] = []
myList (x : xs) = sortEm (x : myList xs)
(untested)
Or in terms of a fold:
myList = foldr cons []
where cons x xs = sortEm (x : xs)
(also untested)
-- if..then..else version
sortEM :: Ord a => [a] -> [a]
sortEM (x:y:xs) = if x < y
then x : sortEM (y:xs)
else y : sortEM (x:xs)
sortEM b = b
-- guard version
sortEM_G :: Ord a => [a] -> [a]
sortEM_G (x:y:xs)
| x < y = x : sortEM_G (y:xs)
| otherwise = y : sortEM_G (x:xs)
sortEM_G b = b