Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating a list of the gaps in other lists. Type error holding me back,

I'm trying to make a function that lists out the differences of another list. So for [1,3,7,11] it would return [2,4,4]. I'm trying to use list comprehension but I'm running into trouble with the types the functions I wanted to use take. Is it possible to keep this format by converting a [t] to an [int] and back to a [t] again?

{ difflist x y = [ p - q | p<- [x..y],

                           q<- [ ( [1..(length [x..y]) ] !! [x..y] ): []]] }



<interactive>:200:70: error:
    • Couldn't match expected type ‘Int’ with actual type ‘[[Int]]’
    • In the second argument of ‘(!!)’, namely ‘[x .. y]’
      In the first argument of ‘(:)’, namely
        ‘([1 .. (length [x .. y])] !! [x .. y])’
      In the expression: ([1 .. (length [x .. y])] !! [x .. y]) : []
like image 853
user7778287 Avatar asked Dec 14 '22 23:12

user7778287


2 Answers

How about zipWith:

Prelude> let diffList = \x -> zipWith (flip (-)) x (tail x)
Prelude> diffList [1,3,7,11]
[2,4,4]

Edit (due to comments below):

A more specific function declaration could be as follows:

diffList :: Num a => [a] -> [a]
diffList [] = []
diffList l@(_:xs) = zipWith (-) xs l
like image 55
Netwave Avatar answered May 01 '23 14:05

Netwave


I guess @Daniel Sanchez's zipWith idea is perfectly fine. I could just do like

diffs :: Num a => [a] -> [a]
diffs []     = []
diffs (x:xs) = zipWith (-) xs (x:xs)

However i guess there is another good option which is the mapAccumL. We can implement it as follows;

diffs :: Num a => [a] -> [a]

diffs [] = []
diffs    = tail.snd.mapAccumL (\a x -> (x,x-a)) 0
like image 42
Redu Avatar answered May 01 '23 15:05

Redu