0

I am trying to use a recursive function that prints the list that has the maximum length out of the lists resulting from my following code:

allincreasing :: Ord a => [a] -> [[a]]
allincreasing =  map nub  . filter isSorted . subsequences

main = do
print $ allincreasing[3,2,6,4,5,1]

I need to pass the output below to a recursive function that find the one with max length :

[[],[3],[2],[6],[3,6],[2,6],[4],[3,4],[2,4],[5],[3,5],[2,5],[4,5],[3,4,5],[2,4,5],[1]]

I tried to do it using the following code based on my understanding of an answer to this question but I couldn't implement the recursion part well. Here is my attempt:

 longest :: Ord a => [[a]] -> [a]
 longest [y] = y    --base case: if there's only one element left, return it.
 longest (x:y:lst) --extract the first two elements x, y from the list.  
   | length x < length y = longest (y:lst)
   | otherwise  = x : (longest (y:lst))


  lis :: Ord a => [a]  -> a 
  lis = length . longest . allincreasing

Note: I am required to use recursion to solve the problem of longest increasing sequence.

Raghad
  • 55
  • 5

1 Answers1

0

When you want to track stuf alongsiede recursion (like the max list so far...) one use accumulators (you could read about them here...):

Edited due to comment request:

module Main where
import Data.List

isSorted :: (Ord a) => [a] -> Bool
isSorted []       = True
isSorted [x]      = True
isSorted (x:y:xs) = x <= y && isSorted (y:xs)

allincreasing :: Ord a => [a] -> [[a]]
allincreasing =  map nub  . filter isSorted . subsequences

main :: IO ()
main = do

   
    let list = [3,2,6,4,5,1]
    print $ allincreasing list
    print $  longest $ allincreasing list



longest :: Ord a => [[a]] -> [a]
longest list = longest' list [] 
    where
        longest' [] acc = acc
        longest' (x:xs) [] = longest' xs x
        longest' (x:xs) acc 
            | length acc >= length x = longest' xs acc
            | length acc < length x = longest' xs x
        longest' _ _ = error "something went wrong..."
Thomas Meyer
  • 384
  • 1
  • 11
  • This code works very well but I want to pass output of "allincreasing" instead of 'list 'defined manually. I tried to replace all 'list's with allincreasing but it's not working – Raghad Apr 17 '22 at 05:01
  • is your function "isSorted" one of those? - https://stackoverflow.com/questions/22050710/test-if-a-list-is-sorted – Thomas Meyer Apr 17 '22 at 05:35
  • is my edit what you wanted? – Thomas Meyer Apr 17 '22 at 06:03
  • Exactly! Appreciated – Raghad Apr 17 '22 at 06:32
  • I noticed that if two sublists are equal it only returns the first one, for example, the output here is only [3,4,5] while [2,4,5] has the same length. Is there a way to return both of them? – Raghad Apr 17 '22 at 22:36
  • to return _all_ lists with the biggest length, first you need to change the return type from `[a]` to `[[a]]`. – Will Ness Apr 18 '22 at 13:40
  • @WillNess and then? what else should I change? – Raghad Apr 18 '22 at 14:17
  • @Raghad you should change the `acc` accordingly, since that's the value being returned in the base case of the recursion. instead of being the first encountered longest list, it will be a _list_ of all the longest lists encountered so far. – Will Ness Apr 18 '22 at 20:25
  • @ThomasMeyer Any suggestions? – Raghad Apr 18 '22 at 21:02
  • @Raghad new question, new post. this one is answered. – Will Ness Apr 19 '22 at 03:59