# Create a new list with a difference from each value

I'm trying to make a function that does the following: it gets a list, for example `[1,4,2,3]`

, and returns a list `[3,2,1]`

.

Because `1 - 4 = 3`

(abs value), `4 - 2 = 2`

and `2 - 3 = 1`

.

I thought this piece of code would do it except for the abs value.

``````function :: [a] -> [a]
function [] = []
function (x:xs) = [x - head(xs)] ++ function xs
```

```

but this is giving me errors and I haven't found any solution.

Respectfully,

EDIT:

Thanks guys, you learned a lot today. Indeed I am a beginner, I have a university course that gives me prologue, haskell, scala, python, aspectj and metaprogramming. Thus, we have for each program 2 lessons with 2 hours, and then some time to do some exercises.

Next Monday I have an exam and zipwith etc ... we have to write our own function. But thanks for the nice tutorial explained, learned so much. This is a working solution:

``````function :: Num a => [a] -> [a]
function (x:y:xs) = [abs(x - y)] ++ function (y:xs)
function _ = []
```

```
+3

source to share

If you are still interested in a recursive solution .

``````No instance for (Num a)
arising from a use of `-'
In the expression: x - head (xs)
In the first argument of `(++)', namely `[x - head (xs)]'
In the expression: [x - head (xs)] ++ function xs
```

```

The operator `(-) :: Num a => a -> a -> a`

requires its arguments to be `Num`

. Therefore, we can fix it with `function :: Num a => [a] -> [a]`

.

We now have another problem:

``````> function [1,4,2,3]
```

```

Therefore, we have to handle some cases:

``````function :: Num a => [a] -> [a]
function [] = []
function [_] = []
function (x:xs) = x - head xs : function xs
```

```

But this is still not what we actually expected:

``````> function [1,4,2,3]
[-3,2,-1]
```

```

So, we have to add a function `abs`

:

``````function :: Num a => [a] -> [a]
function [] = []
function [_] = []
function (x:xs) = abs ( x - head xs ) : function xs
```

```

Done

``````> function [1,4,2,3]
[3,2,1]
```

```

Also, you can do it very simply and with more readable code.

How can you tell the difference between the two lists? `zipWith`

looks really useful. For example:

``````> zipWith (-) [1,2,3,4] [1,1,1]
[0,1,2]
```

```

So the idea is the `zipWith (-)`

original list and `tail`

.

``````> let x = [1,2,3,4]
> zipWith (-) x (tail x)
[-1,-1,-1]
```

```

And you may like yours `function`

:

``````function :: Num a => [a] -> [a]
function x = map abs \$ zipWith (-) x (tail x)
```

```

Done

``````> function [1,4,2,3]
[3,2,1]
```

```
+5

source

In general, it is a good idea to tell us what errors you get, rather than expecting us to inject your code and run it ourselves. But here's what I see right away:

• `function :: [a] -> [a]`

means it `function`

works for any type of list. But you will say later `x - head(xs)`

. Here we have `x :: a`

and `head(xs) :: a`

. You would expect the subtraction operator to accept any two values ​​as long as they are of the same type.

But `(-) :: Num a => a -> a -> a`

; one type is not enough for these two values, this type must implement `Num`

typeclass (which also provides addition, multiplication, absolute value, and several other functions).

Fix: Replace type signature `function :: Num a => [a] -> [a]`

.

• The code should now compile, but when you run it, you will get an error with the title of an empty list.

Let's walk through what happens when we run `function `

* :

• The first equation has `function []`

on the left, but ``

doesn't match `[]`

, so skip it.

• The second equation has `function (x:xs)`

the left side. ``

matches `(x:xs)`

by giving us `x = 4`

and `xs = []`

, so we will continue with this equation and estimate `[4 - head([])] ++ function []`

.

• This includes a score `[4 - head([])]`

that includes a score `4 - head([])`

that includes a score `head([])`

, which is an error because an empty list has no head.

Fix: Think about what we want here. When we match a pattern to a list, it's not enough to know that it has a head ( `x`

). We also need to know that it has a second item ( `y`

). Therefore, we replace the equations by

``````function (x:y:xs) = [x - y] ++ function (y:xs)
function _        = []
```

```

`_`

matches any value at all. The first equation is the same when the list contains two or more items, so the second equation will clean up the list of empty lists and single items.

* : I am not saying that it really scores in that order. But this is clean code (and final data), so it doesn't matter what order we evaluate.

• You really don't want to do explicit recursion yourself if you can help it, you want to use a higher-order function instead; partly because it means you don't have to write the recursion yourself (and risk getting it wrong), and partly because you can often dodge pattern matching with a higher-order function (avoiding, perhaps, that it's wrong ). So take the advice of sclv: use `zipWith`

and `drop 1`

(and ignore Daniel Fischer's this one time: you don't want to get used to having to worry about how safe to use `head`

, for granted, when `drop 1 []`

bringing `[]`

is useful).

Other advantages of using a higher-order function instead of pattern matching and explicit recursion:

• only one equation is required
• easier to identify what the code is doing
• more efficient code
+5

source

take a look at `zipWith`

and `drop 1`

...

+4

source

Dmitri's solution could be improved

``````function :: Num a => [a] -> [a]
function x = map abs \$ zipWith (-) x (tail x)
```

```

We really want to get the result `(-)`

and "feed" it immediately to the function `abs`

, avoiding the extra step `map`

. Doing it with a lambda expression is pretty ugly:

``````function :: Num a => [a] -> [a]
function x = zipWith (\a b -> abs(a - b)) x (tail x)
```

```

The magic sauce is called "functional composition" and uses an operator `(.)`

. `(f . g) x`

means simple `f(g x)`

but cool that we can glue our functions together and provide an argument later . Using this we get:

``````function :: Num a => [a] -> [a]
function x = zipWith ((abs.).(-)) x (tail x)
```

```

(Corrected after is7s' note, this is a bit tricky since we have to deal with two arguments here)

0

source

I don't know if this suits all your needs, but it worked in ghci:

``````let func a = [ abs( fst x - snd x ) | x <- zip a (tail a)]
```

```

Performance: `func [1,4,2,3]`

Returns: `[3,2,1]`

As expected.

I'm still getting started, but I also want to help when I find out.

0

source

All Articles