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]) : []
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With