-9

I have this piece of python code that I would like to translate to haskell:

T = int(input())
for t in range(0, T):

  n = int(input())
  a = list(map(int, input().split()))

  lis = [[0 for j in range(0, n)] for i in range(0, n)]

  for i in range(0, n):
      for j in range(i, n):
          val = 1
          for k in range(i, j):
              if(a[k] < a[j] and 1 + lis[i][k] > val):
                  val = 1 + lis[i][k]
          lis[i][j] = val
  ans = ''

I want to be able to create a function in haskell that can do this. However, This program essentially take take from an input such as

1
5
1 2 9 6 8

where the first line is the number of test cases and the second line being the number of numbers in the specific test case, and the third line being the test case itself. It is looking for the multiple increasing sequences within the test case

  • 3
    In functional programming, you can not assign values do variables. All variables are immutable: once set, you can not set the variable to another value, you can however *return* a value, or use recursion. Therefore in Haskell there is no `if`, there is only an `if`-`else`, since you need to `return` something in the case the condition does *not* hold. – Willem Van Onsem Apr 08 '18 at 21:32
  • 3
    The code lacks too much context. It's not even clear what its purpose is in python, let alone how to approach the same problem in haskell. – Bergi Apr 08 '18 at 21:33
  • 1
    You can write an expression that returns the desired value rather than doing an assignment, but I don't think there is much value in answering this without you providing an attempt to solve the problem. A little context would also be helpful. – madgen Apr 08 '18 at 21:43
  • I have updated the question! – John Gringus Apr 08 '18 at 21:44
  • 1
    @JohnGringus Since you originally asked about the code inside the loop, did you already succeed at implementing the rest? Specifically, reading the input is something that should be separated from the actual logic. Writing a function that takes only the `a` as an argument (and then computes the final `lis` from it) would be appropriate. – Bergi Apr 08 '18 at 21:54
  • Yes, I have already read the lines from a file and placed each line in to different variable. – John Gringus Apr 08 '18 at 21:59
  • I am also using ForM as the for loops. Is that bad practice? – John Gringus Apr 08 '18 at 22:02
  • @JohnGringus There's nothing wrong with `forM` or `forM_` per se, but whether or not exactly what you're doing is bad practice or not is impossible to say without you actually telling us what you're doing. – Cubic Apr 09 '18 at 15:10

2 Answers2

1

I will answer your question exactly how did you ask, but when you are converting from python or other object oriented language to functional programming you cannot proceed exactly in the same way. And most of the times, you have to come up with a little bit different logic. Its hard for me to help you more, because you send a really short piece of code and little of information.

However, probably you want some function, which is working with all the variables you are using in this piece of code, so a, k, j, i, val, lis also for this function is I think the best to use return type Maybe, which will return Nothing if you didnt change val or Just val with new value. For array/list indexing you can use operator !!.

fun a k j i val lis 
    | a!!k < a!!j && 1 + (lis!!i)!!k > val = Just (1 + (lis!!i)!!k)
    | otherwise = Nothing

But like I said before... I think you are probably doing some for cycles etc.. And for that its much better to use pattern matching and recursion in Haskell...

Hope I helped you...

Vojtěch Mráz
  • 1,116
  • 1
  • 9
  • 19
1

On asking questions

How to create a function that does an if check and then returns a value?

If this really were your question, this would answer it:

fun :: () -> String
fun () = if 5 > 6 then "You're nuts!" else "Obviously!"

But perhaps your title should be "Multiple increasing sequences in Haskell".

I have this piece of python code that I would like to translate to Haskell: [...]

I want to be able to create a function in Haskell that can do this.

So you want to translate some code; but what is your question? Are you asking for others to translate it, or give hints as to how to translate particular bits? Or more generally how to translate from one programming paradigm into another?

How can others enable you to create such a function in Haskell? If you're stuck at "How do I even make a function and an if-clause?", then perhaps should your question be How to get started with Haskell? Remember you clicked the "Ask Question" button, not the "Make Demands" button. ;-)

This program essentially take take from an input such as

1
5
1 2 9 6 8

where the first line is the number of test cases and the second line being the number of numbers in the specific test case, and the third line being the test case itself. It is looking for the multiple increasing sequences within the test case

This seems to be the actual question, except you don't really say what the "multiple increasing sequences" problem is. If you want help on problem solving, you have to state the problem.

On structuring your algorithm in Haskell

Without knowing exactly what your problem is, it seems that it consists of n sub-problems parsed from standard input; each sub-problem being contained in an array of integers. So you can at least build the following two parts:

  1. Extracting the problem via I/O:

    import Control.Monad (replicateM)
    
    -- Read a line that contains an Int.
    readInt :: IO Int
    readInt = undefined
    
    -- Read a line that contains multiple Ints.
    readInts :: IO [Int]
    readInts = fmap (map read . words) getLine
    
    -- Read n problems.
    readProblems :: IO [[Int]]
    readProblems = readInt >>= \n -> replicateM n (readInt >> readInts)
    
  2. Solving a problem without I/O:

    solveProblem :: [Int] -> Int
    solveProblem ns = undefined
    
  3. Piecing those parts together:

    main :: IO ()
    main = do
      problems <- readProblems
      forM problems (print . solveProblem)
    
sshine
  • 15,635
  • 1
  • 41
  • 66