Why does this code give no error, but does not return anything?

2

I'm still learning Haskell (actually only started about 2 days ago) with a basic C # knowledge.

In this piece of code the code is supposed to iterate several times in a list and subtract the first value from the second until it finishes. The problem is that when I run the code it does not give errors, but it goes into a kind of infinite loop, because nothing happens.

sub :: [Float] -> Float
sub [] = 0
sub (x : xs) = sub ( subtract (head xs) x : xs)

I've also tried this code, but it just subtracts the first 2 values from the list. I know more or less why, but I do not know how to solve it.

sub :: [Float] -> Float
sub [] = 0
sub (x : xs) = subtract (head xs) x

Thanks for the help.

    
asked by anonymous 06.10.2017 / 21:01

1 answer

0

The main missing point was to call the sub function again correctly. I do not quite understand what you want to do, see if the iteration below is the expected result:

Input: [1,2,3,4]

1. [1,2,3,4] -- (2 - 1) (2° posição - 1° posição)
2. [1,1,3,4] -- (3 - 1) (3° posição - 2° posição)
3. [1,1,2,4] -- (4 - 2) (4° posição - 3° posição)
4. [1,1,2,2] -- Final

In this case we are subtracting the next position by the result already subtracted. If this is what you need then the code is as follows:

sub :: [Int] -> [Int]
sub [] = []
sub (x:xs)
  | length xs == 0 = [x]
  | otherwise = [x] ++ sub ([y - x] ++ drop 1 xs)
  where y = head(xs)

main = do
  let list = [1,2,3,4]
  print $ sub list -- [1,1,2,2]

I'm using Guards (similar to the switch / case) which says that if the tail is of size 0 it returns the value itself (This is necessary since head (xs) can not receive an empty list and also helps in lists with only 1 value). If the list's tail is greater than 0 I concatenate x and use sub in a new list which is the concatenation of the subtraction done with the tail minus 1 element on the left. It's a bit confusing indeed but I'll do the iterations to get easier:

Input: [1,2,3,4]

1. [1] ++ sub ([2 - 1, 3, 4])
2. [1] ++ sub ([3 - 1, 4])
3. [2] ++ sub ([4]) -- apenas 1 elemento retorna o elemento
4. [1,1,2,2] -- Final
    
08.10.2017 / 17:42