I am trying to figure out how to create a recursive function that will find the largest element in the list and delete it then return the list. This is what i have so far but the problem is that every time i run it it returns the list without any of the values that are assigned to x.
deleteMax :: (Ord a) => [a] -> [a]
deleteMax [] = []
deleteMax [x] = []
deleteMax (x:y:xs)
|x == y = y: deleteMax xs
|x >= y = y: deleteMax xs
|x < y = x: deleteMax xs
This is not your answer
So you are a beginner and as such would like the simple solution of "how do I find the largest element in a list" followed by "how do I remove (one of the) largest element(s) in the list". This isn't that answer but it is me avoiding a long comment while also giving you something to come back to in 3 months.
The Lazy Way
One solution, which #n.m. and I were sparring about in comments, is to tie the knot (Googleable term). In this method you only need one logical pass over the list. In this case it is basically a trick to hide the pass that constructs the result list.
The idea is that during your pass over the list you do both tasks of 1. Compute the maximum element and 2. Compare with the maximum element and construct the list. There is nothing here that requires a monad but it can be easiest to see as part of a state monad:
deleteMaxState :: (Ord a) => [a] -> [a]
deleteMaxState [] = []
First we handle the base cases so we have a candidate 'maximum' (x) for our recursive operation.
deleteMaxState xs#(fstElem:_) =
let (r,(m,_)) = runState (go xs) (fstElem, notMax m)
notMax mx v = if (mx > v) then (v:) else id
go [] = return []
go (x:xs) =
do (curr,f) <- get
when (x > curr) (put (x,f))
f x <$> go xs
in r
In the loopwe track two values the first, curr, is the largest observed value by this point in our traversal of the list. The second value, f, is the trick - it is (a function including) the maximum value provided to the computation after the traversal has completed.
The magic is all here:
(r,(m,_)) = runState (go xs) (fstElem, m)
The left element of the result state (m,_) was our running maximum. Once the traversal ends we use that value - it becomes the right element (fstElem, m) and thus represents the maximum of the whole list.
We can use f to create thunks that populate portions of the list or just in-line construct our list as a bunch of unevaluated cons computations.
Making this one iota simpler, we can remove the higher-order function f and just have a number (untested):
deleteMaxState xs#(fstElem:_) =
let (r,(m,_)) = runState (go xs) (fstElem, m)
go [] = return []
go (x:xs) =
do (curr,theMax) <- get
when (x > curr) (put (x,theMax))
((if x >= theMax then Nothing else Just x) :) <$> go xs
in catMaybes r
Now we can see the second pass pretty explicitly not just as an unevaluated set of "some computation involving max, consed on the result" but as an actual pass via catMaybes.
The tying of the knot allows the programmer to write one logical traversal. This can be nice since it requires only one pattern match and recursive call per constructor of the list elements but at the cost of reasoning about evaluation order.
Related
What is the difference between this two, in terms of evaluation?
Why this "obeys" (how to say?) non-strictness
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter _ [] = []
recFilter p (h:tl) = if (p h)
then h : recFilter p tl
else recFilter p tl
while this doesn't?
recFilter :: (a -> Bool) -> [a] -> Int -> [a]
recFilter _ xs 0 = xs
recFilter p (h:tl) len
| p(h) = recFilter p (tl ++ [h]) (len-1)
| otherwise = recFilter p tl (len-1)
Is it possible to write a tail-recursive function non-strictly?
To be honest I also don't understand the call stack of the first example, because I can't see where that h: goes. Is there a way to see this in ghci?
The non-tail recursive function roughly consumes a portion of the input (the first element) to produce a portion of the output (well, if it's not filtered out at least). Then recursion handles the next portion of the input, and so on.
Your tail recursive function will recurse until len becomes zero, and only at that point it will output the whole result.
Consider this pseudocode:
def rec1(p,xs):
case xs:
[] -> []
(y:ys) -> if p(y): print y
rec1(p,ys)
and compare it with this accumulator-based variant. I'm not using len since I use a separate accumulator argument, which I assume to be initially empty.
def rec2(p,xs,acc):
case xs:
[] -> print acc
(y:ys) -> if p(y):
rec2(p,ys,acc++[y])
else:
rec2(p,ys,acc)
rec1 prints before recursing: it does not need to inspect the whole input list to start printing its output. It works in a "steraming" fashion, in a sense. Instead, rec2 will only start to print at the very end, after the input list was completely scanned.
In your Haskell code there are no prints, of course, but you can thing of returning x : function call as "printing x", since x is made available to the caller of our function before function call is actually made. (Well, to be pedantic this depends on how the caller will consume the output list, but I'll neglect this.)
Hence the non-tail recursive code can also work on infinite lists. Even on finite inputs, performance is improved: if we call head (rec1 p xs), we only evaluate xs until the first non-discarded element. By contrast head (rec2 p xs) would fully filter the whole list xs, even we don't need that.
The second implementation does not make much sense: a variable named len will not contain the length of the list. You thus need to pass this, for infinite lists, this would not work, since there is no length at all.
You likely want to produce something like:
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter p = go []
where go ys [] = ys -- (1)
go ys (x:xs) | p x = go (ys ++ [x]) xs
| otherwise = go ys xs
where we thus have an accumulator to which we append the items in the list, and then eventually return the accumulator.
The problem with the second approach is that as long as the accumulator is not returned, Haskell will need to keep recursing until at least we reach weak head normal form (WHNF). This means that if we pattern match the result with [] or (_:_), we will need at least have to recurse until case one, since the other cases only produce a new expression, and it will thus not yield a data constructor on which we can pattern match.
This in contrast to the first filter where if we pattern match on [] or (_:_) it is sufficient to stop at the first case (1), or the third case 93) where the expression produces an object with a list data constructor. Only if we require extra elements to pattern match, for example (_:_:_), it will require to evaluate the recFilter p tl in case (2) of the first implementation:
recFilter :: (a -> Bool) -> [a] -> [a]
recFilter _ [] = [] -- (1)
recFilter p (h:tl) = if (p h)
then h : recFilter p tl -- (2)
else recFilter p tl
For more information, see the Laziness section of the Wikibook on Haskell that describes how laziness works with thunks.
This question already has answers here:
Eq => function in Haskell
(2 answers)
Closed 3 years ago.
I am new to Haskell and am trying to write quite an easy function which gathers each repeated consecutive elements under separate sub-lists, For example:
f :: Eq a => [a] -> [[a]]
So:
f [] = []
f [3] = [[3]]
f [1,1,1,3,2,2,1,1,1,1] = [[1,1,1],[3],[2,2],[1,1,1,1]]
I thought about this function:
f :: Eq a => [a] -> [[a]]
f [] = []
f (x:[]) = [[x]]
f (x:x':xs) = if x == x' then [[x, x']] ++ (f (xs))
else [[x]] ++ (f (xs))
It seems to not work well since when it arrives to the last element, it wants to compare it to its consecutive, which clearly does not exist.
I would like to receive a simple answer (beginner level) that will not be too different than mine, correcting my code will be the best.
Thanks in advance.
The problem isn't really what you said, it's just that you only hard-coded the cases that either one or two consecutive elements are equal. Actually you want to ground together an arbitrary number of equal consecutives. IOW, for every element, you pop off as many following ones as are equal.
Generally, splitting of the head-part of a list which fulfills some condition is what the span function does. In this case, the condition it's supposed to check is being equal to the element you already removed. That's written thus:
f [] = []
f (x:xs) = (x:xCopies) : f others
where (xCopies,others) = span (==x) xs
Here, x:xCopies puts together the chunk of elements equal to x (with x itself on front), use that as the heading chunk-list of the result, and then you recurse over all the elements that remain.
Your problem is that both halves of your if have the same structure: they cons exactly one element onto the front of the recursive call. This can't be right: sometimes you want to add an element to the front of the list, and other times you want to combine your element with what's already in the recursive call.
Instead, you need to pattern-match on the recursive call to get the first item in the recursive result, and then prepend to that when the first two items match.
f :: Eq a => [a] -> [[a]]
f [] = []
f [x] = [[x]]
f (x:xs#(y:_)) | x == y = (x:head):more
| otherwise = [x]:result
where result#(head:more) = f xs
I think my code to find the mean of a list (of integers) works ok, but has a problem. This is my code
listlen xs = if null xs
then 0
else 1 + (listlen (tail xs))
sumx xs = if null xs
then 0
else (head xs) + sumx (tail xs)
mean xs = if null xs
then 0
else (fromIntegral (sumx xs)) / (fromIntegral (listlen xs))
my mean function has to go through the list twice. Once to get the sum of the elements, and once to get the number of elements. Obviously this is not great.
I would like to know a more efficient way to do this (using elementary Haskell - this is a a question from Real World Haskell chapter 3.)
I like the other answers here. But I don't like that they write their recursion by hand. There are lots of ways to do this, but one handy one is to reuse the Monoid machinery we have in place.
Data.Monoid Data.Foldable> foldMap (\x -> (Sum x, Sum 1)) [15, 17, 19]
(Sum {getSum = 51}, Sum {getSum = 3})
The first part of the pair is the sum, and the second part is the length (computed as the sum of as many 1s as there are elements in the list). This is a quite general pattern: many statistics can actually be cast as monoids; and pairs of monoids are monoids; so you can compute as many statistics about a thing as you like in one pass using foldMap. You can see another example of this pattern in this question, which is where I got the idea.
What #simonzack is alluding to is that you should write listlen and sumx as folds.
Here is listlen written as a fold:
listlen :: [a] -> Int
listlen xs = go 0 xs -- 0 = initial value of accumulator
where go s [] = s -- return accumulator
go s (a:as) = go (s+1) as -- compute the next value of the accumulator
-- and recurse
Here s is an accumulator which is passed from one iteration of the helper function go to the next iteration. It is the value returned when the end of the list has been reached.
Writing sumx as a fold will look like:
sumx :: [a] -> Int
sumx xs = go 0 xs
where go s [] = s
go s (a:as) = go ... as -- flll in the blank ...
The point is that given two folds you can always combine them so they are computed together.
lenAndSum :: [a] -> (Int,Int)
lenAndSum xs = go (0,0) xs -- (0,0) = initial values of both accumulators
where go (s1,s2) [] = (s1,s2) -- return both accumulators at the end
go (s1,s2) (a:as) = go ... as -- left as an exercise
Now you have computed both functions with one traversal of the list.
Define a helper function that only goes through once:
lengthAndSum xs = if null xs
then (0,0)
else let (a,b) = lengthAndSum(tail xs) in (a + 1, b + head xs)
mean xs = let (a, b) = lengthAndSum xs in (fromIntegral b / fromIntegral a)
Now, there's an idea: a function that takes a bunch of monoids and applies each to a list, all at the same time. But that can come later!
I think what you'll need is a fold and a tuple for a good speed:
avg :: (Fractional a) => [a] -> a
avg [] = error "Cannot take average of empty list"
avg nums = let (sum,count) = foldr (\e (s,c) -> (s+e,c+1)) (0,0) nums
in sum / count
I've tried this out, and it's decently speedy in GHCi, though It may not be the best. I thought up a recursive method, too, though it requires a helper function:
avg :: (Fractional a) => [a] -> a
avg [] = error "Cannot take average of empty list"
avg nums = let (sum, count) = go nums
in sum / count
where go [] = (0,0)
go (x:xs) = let (sum',count') = go xs
in (sum' + x, count' + 1)
Then again, that's really slow. Painfully slow.
Looking at your solution, that's alright, but it's not really idiomatic Haskell. if statements within functions tend to work better as pattern matches, especially if the Eq class instance isn't defined for such-and-such a datatype. Furthermore, as my example illustrated, folds are beautiful! They allow Haskell to be lazy and therefore are faster. That's my feedback and my suggestion in response to your question.
Currently I am using
takeWhile (\x -> x /= 1 && x /= 89) l
to get the elements from a list up to either a 1 or 89. However, the result doesn't include these sentinel values. Does Haskell have a standard function that provides this variation on takeWhile that includes the sentinel in the result? My searches with Hoogle have been unfruitful so far.
Since you were asking about standard functions, no. But also there isn't a package containing a takeWhileInclusive, but that's really simple:
takeWhileInclusive :: (a -> Bool) -> [a] -> [a]
takeWhileInclusive _ [] = []
takeWhileInclusive p (x:xs) = x : if p x then takeWhileInclusive p xs
else []
The only thing you need to do is to take the value regardless whether the predicate returns True and only use the predicate as a continuation factor:
*Main> takeWhileInclusive (\x -> x /= 20) [10..]
[10,11,12,13,14,15,16,17,18,19,20]
Is span what you want?
matching, rest = span (\x -> x /= 1 && x /= 89) l
then look at the head of rest.
The shortest way I found to achieve that is using span and adding a function before it that takes the result of span and merges the first element of the resulting tuple with the head of the second element of the resulting tuple.
The whole expression would look something like this:
(\(f,s) -> f ++ [head s]) $ span (\x -> x /= 1 && x /= 89) [82..140]
The result of this expression is
[82,83,84,85,86,87,88,89]
The first element of the tuple returned by span is the list that takeWhile would return for those parameters, and the second element is the list with the remaining values, so we just add the head from the second list to our first list.
I have the following list (it’s a length 2 list, but in my assignment I have a length +n list)
xxs = [(11,22,[(33,33,33),(44,44,44)]),(55,66,[(77,77,77),(88,88,88)])]
I’m trying to “replace” one 3-tuple (p1 or p2 or p3 or p4 from the image bellow) by list index (n) and by sub-list index (p).
The function, at the end, should be like:
fooo newtuple n p = (…)
For example: (replace p3 for (98,98,98):
fooo (98,98,98) 2 1
[(11, 22, [(33,33,33) , (44,44,44)]) , (55, 66, [(98,98,98),(88,88,88)])]
I planned the code like following this steps:
Access the pn that I want to change. I manage to achieve it by:
fob n p = ((aux2 xxs)!!n)!!p
where aux2 [] = []
aux2 ((_,_,c):xs) = c:aux2 xs
“replace” the 3-tuple. I really need some help here. I’m stuck. the best code (in my head it makes some sense) that I’ve done: (remember: please don’t be too bad on my code, I’ve only been studying Haskell only for 5 weeks)
foo n p newtuple = fooAux newtuple fob
where fooAux _ [] = []
fooAux m ((_):ds) = m:ds
fob n p = ((aux2 xxs)!!n)!!p
where aux2 [] = []
aux2 ((_,_,c):xs) = c:aux2 xs
Finally I will put all back together, using splitAt.
Is my approach to the problem correct? I really would appreciate some help on step 2.
I'm a bit new to Haskell too, but lets see if we can't come up with a decent way of doing this.
So, fundamentally what we're trying to do is modify something in a list. Using functional programming I'd like to keep it a bit general, so lets make a function update.
update :: Int -> (a -> a) -> [a] -> [a]
update n f xs = pre ++ (f val) : post
where (pre, val:post) = splitAt n xs
That will now take an index, a function and a list and replace the nth element in the list with the result of the function being applied to it.
In our bigger problem, however, we need to update in a nested context. Luckily our update function takes a function as an argument, so we can call update within that one, too!
type Triple a = (a,a,a)
type Item = (Int, Int, [Triple Int])
fooo :: Triple Int -> Int -> Int -> [Item] -> [Item]
fooo new n p = update (n-1) upFn
where upFn (x,y,ps) = (x,y, update (p-1) objFn ps)
objFn _ = new
All fooo has to do is call update twice (once within the other call) and do a little "housekeeping" work (putting the result in the tuple correctly). The (n-1) and (p-1) were because you seem to be indexing starting at 1, whereas Haskell starts at 0.
Lets just see if that works with our test case:
*Main> fooo (98,98,98) 2 1 [(11,22,[(33,33,33),(44,44,44)]),(55,66,[(77,77,77),(88,88,88)])]
[(11,22,[(33,33,33),(44,44,44)]),(55,66,[(98,98,98),(88,88,88)])]
First, we need a general function to map a certain element of a list, e.g.:
mapN :: (a -> a) -> Int -> [a] -> [a]
mapN f index list = zipWith replace list [1..] where
replace x i | i == index = f x
| otherwise = x
We can use this function twice, for the outer list and the inner lists. There is a little complication as the inner list is part of a tuple, so we need another helper function:
mapTuple3 :: (c -> c) -> (a,b,c) -> (a,b,c)
mapTuple3 f (x,y,z) = (x,y,f z)
Now we have everything we need to apply the replace function to our use case:
fooo :: Int -> Int -> (Int,Int,Int) -> [(Int,Int,[(Int,Int,Int)])]
fooo n p newTuple = mapN (mapTuple3 (mapN (const newTuple) p)) n xxs
Of course in the inner list, we don't need to consider the old value, so we can use const :: a -> (b -> a) to ignore that argument.
So you've tried using some ready-made function, (!!). It could access an item in a list for you, but forgot its place there, so couldn't update. You've got a solution offered, using another ready-made function split, that tears a list into two pieces, and (++) which glues them back into one.
But to get a real feel for it, what I suspect your assignment was aiming at in the first place (it's easy to forget a function name, and it's equally easy to write yourself a new one instead), you could try to write the first one, (!!), yourself. Then you'd see it's real easy to modify it so it's able to update the list too.
To write your function, best think of it as an equivalence equation:
myAt 1 (x:xs) = x
myAt n (x:xs) | n > 1 = ...
when n is zero, we just take away the head element. What do we do when it's not? We try to get nearer towards the zero. You can fill in the blanks.
So here we returned the element found. What if we wanted to replace it? Replace it with what? - this calls another parameter into existence,
myRepl 1 (x:xs) y = (y:xs)
myRepl n (x:xs) y | n > 1 = x : myRepl ...
Now you can complete the rest, I think.
Lastly, Haskell is a lazy language. That means it only calls into existence the elements of a list that are needed, eventually. What if you replace the 7-th element, but only first 3 are later asked for? The code using split will actually demand the 7 elements, so it can return the first 3 when later asked for them.
Now in your case you want to replace in a nested fashion, and the value to replace the old one with is dependent on the old value: newVal = let (a,b,ls)=oldVal in (a,b,myRepl p ls newtuple). So indeed you need to re-write using functions instead of values (so that where y was used before, const y would go):
myUpd 1 (x:xs) f = (f x:xs)
myUpd n ... = ...
and your whole call becomes myUpd n xxs (\(a,b,c)->(a,b,myUpd ... (const ...) )).