fold function keep switching var locations - haskell

I want to write a function which takes a list of integers and returns a list where every element is negative.
negate :: [Int] -> [Int]
negate xs = foldl (\x xs -> (abs x * (-1)) : xs) [] xs
This function negate all the array objects but also reverse the locations of all variables in the array. What make this function reverse the locations?

foldl does! foldl is a left fold, so it works on your list by starting with its initial state (which you provide as []) and the leftmost element of the list, and calls your function which prepends the negation of that element to the state. Then it takes the next leftmost element and does the same thing. But you're prepending each time, which means that the first element of your input ends up corresponding to the last element of the output, because it was the first to get prepended.
You might want foldr for this, which is a fold that starts with the rightmost element. Alternatively, using map would be a simpler approach for this particular problem.
Sample code:
makeAllNegative = map (negate . abs)

Related

How to create Haskell function that returns every third element from a list of ints

I want to create a function that returns every third int from a list of ints without using any predefined functions. For example, everyThird [1,2,3,4,5] --> [1,4]
everyThird:: [a] -> [a]
Could I just continue to iterate over the list using tail and appending to a new list every third call? I am new to Haskell and very confused with all of this
One other way of doing this is to handle three different base cases, in all of which we're at the end of the list and the list is less than three elements long, and one recursive case, where the list is at least three elements long:
everyThird :: [a] -> [a]
everyThird [] = []
everyThird [x] = [x]
everyThird [x, _] = [x]
everyThird (x:_:_:xs) = x:everyThird xs
You want to do exactly what you said: iterate over the list and include the element only on each third call. However, there's a problem. Haskell is a funny language where the idea of "changing" a variable doesn't make sense, so the usual approach of "have a counter variable i which tells us whether we're on the third element or not" won't work in the usual way. Instead, we'll create a recursive helper function to maintain the count for us.
everyThird :: [Int] -> [Int]
everyThird xs = helper 0 xs
where helper _ [] = []
helper 0 (x : xs) = x : helper 2 xs
helper n (_ : xs) = helper (n - 1) xs
We have three cases in the helper.
If the list is empty, stop and return the empty list.
If the counter is at 0 (that is, if we're on the third element), make a list starting with the current element and ending with the rest of the computation.
If the counter is not at zero, count down and continue iteration.
Because of the way pattern matching works, it will try these three statements in order.
Notice how we use an additional argument to be the counter variable since we can't mutate the variable like we would in an imperative language. Also, notice how we construct the list recursively; we never "append" to an existing list because that would imply that we're mutating the list. We simply build the list up from scratch and end up with the correct result on the first go round.
Haskell doesn't have classical iteration (i.e. no loops), at least not without monads, but you can use similar logic as you would in a for loop by zipping your list with indexes [0..] and applying appropriate functions from Data.List.
E.g. What you need to do is filter every third element:
everyThirdWithIndexes list = filter (\x -> snd x `mod` 3 == 0) $ zip list [0..]
Of course you have to get rid of the indexes, there are two elegant ways you can do this:
everyThird list = map (fst) . everyThirdWithIndexes list
-- or:
everyThird list = fst . unzip . everyThirdWithIndexes list
If you're not familiar with filter and map, you can define a simple recursion that builds a list from every first element of a list, drops the next two and then adds another from a new function call:
everyThird [] = [] -- both in case if the list is empty and the end case
everyThird (x:xs) = x : everyThird (drop 2 xs)
EDIT: If you have any questions about these solutions (e.g. some syntax that you are not familiar with), feel free to ask in the comments. :)
One classic approach:
everyThird xs = [x | (1,x) <- zip (cycle [1..3]) xs]
You can also use chunksOf from Data.List.Split to seperate the lists into chunks of 3, then just map the first element of each:
import Data.List.Split
everyThird :: [a] -> [a]
everyThird xs = map head $ chunksOf 3 xs
Which works as follows:
*Main> everyThird [1,2,3,4,5]
[1,4]
Note: You may need to run cabal install split to use chunksOf.

separate List by heads

I have problems trying to separate a list follows, suppose we have the following lists
[[1,2,3,4], [5,6,7,8], [9,10,11,12 ], [13,14,15,16,17]].
The result should be:
[[1,5,9,13] [2,6,10,14] [3,7,11,16] [4,8,12,16]]
I'm trying to do it the following way:
joinHead (x: xs) = map head (x: xs)
separateLists (x: xs) = xs joinHead x ++ separateLists
obviously this does not work. I hope you can help me. thx.
I adapted the functions you wrote, joinHead and separateLists, to make the code work, while preserving the logic you were following. From what I could infer looking at these functions, the idea was to use joinHead to extract the first element of each child list and return a new list. Then, this new list should be inserted in the front of a list of lists returned from calling separateLists recursively.
Here is the new definition of joinHead:
joinHead :: [[a]] -> [a]
joinHead ([]:_) = []
joinHead xs = map head xs
Note that the first line checks, through pattern matching, whether the first list contained in the list of lists is empty and, if so, returns an empty list ([]). The reasons for that are two:
The function head is unsafe. That means that calling head on an empty list will cause an exception to be thrown (try running in GHCi head []);
For simplicity, I'm assuming that all the lists were already checked to have the same length (length (xs !! 0) == length (xs !! 1) ...).
The definition of separateLists is as follows:
separateLists :: [[a]] -> [[a]]
separateLists ([]:_) = []
separateLists ([x]:xs) = [joinHead ([x]:xs)]
separateLists xs = joinHead xs : separateLists (map tail xs)
Again, the first two definitions are necessary for both stopping the recursion and safety purposes. The first line says: "if the first list is empty, then all the elements of all lists were already consumed, so return []". The second line says: "if the first line has exactly one element, then just call joinHead and return the result wrapped in a list". Note that in the third definition we have a call to tail which, like head, throws exceptions when called on []. That's the reason of why we need a separate case for lists of length 1. Finally, the third line, which is executed for lists of length greater than 1, gets a list from joinHead xs and insert it (using the "cons" operator (:)) in the beginning of the list returned from recursively calling separateLists. In this call, we have to take out the first elements of all the lists, that's why we use map tail xs.
Now, running:
λ: let list = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16,17]]
λ: separateLists list
[[1,5,9,13],[2,6,10,14],[3,7,11,15],[4,8,12,16]]
will give you the expected results. I hope it was clear enough. As a final note, I want to point out that this implementation is far from being optimal and, as suggested in the comments, you should probably use the standard Data.List.transpose. As an exercise and didatic example, it's fine! ;-)

Haskel '!!' defined in foldl

I just started learning Haskell and I'm trying to define the "Get n'th element of list" (with the !! operator) in a function which uses foldl. I now defined it without foldl, just making use of recursion. I wondered if anybody could tell me how to change the code I have to a function with foldl, and could describe what is happening. Thanks in advance!
get 1 (x:_) = x
get i (_:xs) = elementAt'' (i - 1) xs
A couple of notes:
First note that you want get 1 to return the first element in your list, that's not the common choice in many languages including Haskell ([2, 3, 5] !! 1 = 3).
Second, although elementAt is a recursive function over lists, it can be defined more efficiently in the old fashion recursive way. fold functions are not good choices here, because fold goes through every element of the list. But we want elementAt recursion to stop the moment that we find the element.
Given this, here is how you can implement elementAt recursively:
elementAt :: Int -> [a] -> a
elementAt i (x:xs) = if i == 1 then x else elementAt (i-1) xs
And here's the implementation using foldl:
elementAt' :: Int -> [a] -> a
elementAt' i (x:xs) =
snd $
foldl
(\(j, a) b ->
if j < 1 then (j-1, a) else (j-1, b))
(i-1, x)
xs
The seed value of foldl is a tuple: (i-1, x) where x is the head of the list.
Note that the return result of fold functions must be of the same type of their seed. Hence here foldl returns a tuple: (j-1, a) where a is the final result, if the index is found; otherwise (j-1, b) where b is the current element of the list.
You can see how foldl goes through every element of the list even after it found the element at index that we were looking for (it keeps returning the previous result a that will be the final result).
PS. These elementAt functions are not handling the case for empty lists or when i is greater than the length of the list; hence they're not exhaustive.
I can see the following, a bit cryptic way of using foldl for your purpose (it is using zero-based indexing, but can be changed easily to 1-based):
get i lst=
snd $
foldl (\p (j, y) -> if j == i then (j,y) else p ) (0, 0) (zip [0,1..] lst)
The foldl part is working with tuples (index, element), whose list is generated by zipping the given list with indices list. The function passed to foldl as first argument is comparing the index of the desired element with the index with currently passed, and returning the current element if the index is matching, or the previous element otherwise. Then, in the end by using snd only the element part of the tuple is returned.

Haskell: min distance between neighbor numbers on a list

I'm trying to define a functino that finds the minimum distance between to neighbor numbers on a list
something like this:
minNeighborsDistance [2,3,6,2,0,1,9,8] => 1
My code looks like this:
minNeighborsDistance [] = []
minNeighborsDistance (x:xs) = minimum[minNeighborsDistance xs ++ [subtract x (head xs)]]
Although this seems to run, once I enter a list I receive an Exception error.
I'm new to Haskell I would appreciate any help in this matter.
If you pass a singleton list to minNeighborsDistance then
It'll fail to match [] in the first line, then
it'll successfully match (x:xs) assigning the single value to x and the empty like to xs, then
it'll throw an error when you try to access the head of an empty list.
Further, since you call minNeighborsDistance recursively then you'll always eventually call it on a singleton list excepting when you pass it an empty list.
Here's what I came up with:
minDistance l = minimum . map abs . zipWith (-) l $ tail l
Try this:
minDistance list = minimum (distance list)
where
distance list = map abs $ zipWith (-) list (tail list)
distance calculates the absolute value of the list being subtracted with itself shifted by 1 position:
[2,3,6,2,0,1,9,8] -- the 8 is skipped but it does not make a difference
- [3,6,2,0,1,9,8]
= [1,3,4,2,1,8,1]
minDistance now just gets the smallest element of the resulting list.
Your question is a bit unclear (a type signature would really help here), but if you're wanting to calculate the difference between adjacent elements of the list, then find the minimum of those numbers, I would say the most clear way is to use some extra pattern matching:
-- Is this type you want the function to have?
minNeighborsDistance :: [Int] -> Int
minNeighborsDistance list = minimum $ go list
where
go (x:y:rest) = (x - y) : go (y:rest)
go anythingElse = [] -- Or just go _ = []
However, this won't quite give you the answer you want, because the actual minimum for your example list would be -4 when you go from 6 to 2. But this is an easy fix, just apply abs:
minNeighborsDistance :: [Int] -> Int
minNeighborsDistance list = minimum $ go list
where
go (x:y:rest) = abs (x - y) : go (y:rest)
go anythingElse = []
I've used a helper function to calculate the differences from element to element, then the top-level definition calls minimum on that result to get the final answer.
There is an easier way, though, if you exploit a few functions in Prelude, namely zipWith, map, and drop:
minNeighborsDistance :: [Int] -> Int
minNeighborsDistance list
= minimum -- Calculates the minimum of all the distances
$ (maxBound:) -- Ensures we have at least 1 number to pass to
-- minimum by consing the maximum possible Int
$ map abs -- Ensure all differences are non-negative
-- Compute the difference between each element. I use "drop 1"
-- instead of tail because it won't error on an empty list
$ zipWith (-) list (drop 1 list)
So combined into one line without comments:
minNeighborsDistance list = minimum $ (maxBound:) $ map abs $ zipWith (-) list $ drop 1 list

Haskell: Minimum sum of list

So, I'm new here, and I would like to ask 2 questions about some code:
Duplicate each element in list by n times. For example, duplicate [1,2,3] should give [1,2,2,3,3,3]
duplicate1 xs = x*x ++ duplicate1 xs
What is wrong in here?
Take positive numbers from list and find the minimum positive subtraction. For example, [-2,-1,0,1,3] should give 1 because (1-0) is the lowest difference above 0.
For your first part, there are a few issues: you forgot the pattern in the first argument, you are trying to square the first element rather than replicate it, and there is no second case to end your recursion (it will crash). To help, here is a type signature:
replicate :: Int -> a -> [a]
For your second part, if it has been covered in your course, you could try a list comprehension to get all differences of the numbers, and then you can apply the minimum function. If you don't know list comprehensions, you can do something similar with concatMap.
Don't forget that you can check functions on http://www.haskell.org/hoogle/ (Hoogle) or similar search engines.
Tell me if you need a more thorough answer.
To your first question:
Use pattern matching. You can write something like duplicate (x:xs). This will deconstruct the first cell of the parameter list. If the list is empty, the next pattern is tried:
duplicate (x:xs) = ... -- list is not empty
duplicate [] = ... -- list is empty
the function replicate n x creates a list, that contains n items x. For instance replicate 3 'a' yields `['a','a','a'].
Use recursion. To understand, how recursion works, it is important to understand the concept of recursion first ;)
1)
dupe :: [Int] -> [Int]
dupe l = concat [replicate i i | i<-l]
Theres a few problems with yours, one being that you are squaring each term, not creating a new list. In addition, your pattern matching is off and you would create am infinite recursion. Note how you recurse on the exact same list as was input. I think you mean something along the lines of duplicate1 (x:xs) = (replicate x x) ++ duplicate1 xs and that would be fine, so long as you write a proper base case as well.
2)
This is pretty straight forward from your problem description, but probably not too efficient. First filters out negatives, thewn checks out all subtractions with non-negative results. Answer is the minumum of these
p2 l = let l2 = filter (\x -> x >= 0) l
in minimum [i-j | i<-l2, j<-l2, i >= j]
Problem here is that it will allow a number to be checkeed against itself, whichwiull lend to answers of always zero. Any ideas? I'd like to leave it to you, commenter has a point abou t spoon-feeding.
1) You can use the fact that list is a monad:
dup = (=<<) (\x -> replicate x x)
Or in do-notation:
dup xs = do x <- xs; replicate x x; return x
2) For getting only the positive numbers from a list, you can use filter:
filter (>= 0) [1,-1,0,-5,3]
-- [1,0,3]
To get all possible "pairings" you can use either monads or applicative functors:
import Control.Applicative
(,) <$> [1,2,3] <*> [1,2,3]
[(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
Of course instead of creating pairs you can generate directly differences when replacing (,) by (-). Now you need to filter again, discarding all zero or negative differences. Then you only need to find the minimum of the list, but I think you can guess the name of that function.
Here, this should do the trick:
dup [] = []
dup (x:xs) = (replicate x x) ++ (dup xs)
We define dup recursively: for empty list it is just an empty list, for a non empty list, it is a list in which the first x elements are equal to x (the head of the initial list), and the rest is the list generated by recursively applying the dup function. It is easy to prove the correctness of this solution by induction (do it as an exercise).
Now, lets analyze your initial solution:
duplicate1 xs = x*x ++ duplicate1 xs
The first mistake: you did not define the list pattern properly. According to your definition, the function has just one argument - xs. To achieve the desired effect, you should use the correct pattern for matching the list's head and tail (x:xs, see my previous example). Read up on pattern matching.
But that's not all. Second mistake: x*x is actually x squared, not a list of two values. Which brings us to the third mistake: ++ expects both of its operands to be lists of values of the same type. While in your code, you're trying to apply ++ to two values of types Int and [Int].
As for the second task, the solution has already been given.
HTH

Resources