Using map to replace elements of a list with (x-y)*(x-y), where y is the initial element

14,311

Solution 1

First of all, you should probably create a separate function that does what you want.

e.g.

f x y = (x-y)*(x-y)

Now, every time you create a function in Haskell with multiple parameters, it actually "curries" the function, which means that you get a new function when you apply the first argument to it.

So, you would get a new function by doing this

g = f 5

The expression f 5 is actually a function

And you can apply a number to 'g' and x will always be '5'

So if we want to create a function that takes two parameters, 'x' and 'y', and applies (x-y)*(x-y) to a list where y is the current element, then all we need to do is the following:

f x y = (x-y)*(x-y)
squareDifference x = map (f x) [1,2,3,4]

Which you can use by calling squareDifference 5 or any other number as an argument

A more general version would allow you to pass in a list as well

squareDifference x xs = map (f x) xs

Which you would call by doing squareDifference 3 [1,2,3]

Solution 2

do you understand lambda functions?

map (\val -> the function) xs

is what you need.

currying is even better, but not as simple.

edit:

more conceptual...

map iterates down a list applying a function.

map (+ 3) xs

uses the currying technique mentioned above. you could also:

map (\x -> x + 3) xs

to accomplish the same thing.

Solution 3

Simple example:

rela :: Int -> [Int] -> [Int]
rela x = map (\y -> (x-y)*(x-y))

Or might you want any perversions? -) Here you are with Applicatives:

import Control.Applicative
rela :: Int -> [Int] -> [Int]
rela x = map $ (*) <$> (x-) <*> (x-)
Share:
14,311
blane clorley
Author by

blane clorley

Updated on July 09, 2022

Comments

  • blane clorley
    blane clorley almost 2 years

    I have a bit of homework to do and I am a complete newbie to Haskell. The question I am having trouble with is to write a function which when given an integer x and a list of integers apply (x-y)*(x-y) to each element in the list and output the new list, with y being each element of the input list.

    I have a very rough idea I will have to use the map function but I'm unsure how to go about it.

    I have been looking at examples for squaring each element in a list and kind of understand how that works, but how I would implement the (x-y)*(x-y) with y being the current element completely baffles me.

    squares :: [Int] -> [Int]
    squares (x:xs) = x * x : squares xs
    squares [] = []
    

    the exact question I have been set is,

    Write a function rela which takes as arguments an integer x and a list of integers. It returns a similar list, but where each element y has been replaced by (x-y)*(x-y), e.g.

    Main> rela 2 [3,5,7]
    [1,9,25]
    

    I have managed to get it working after reading through some books, but the code I have made misses out the first element in the list. Any explanation why?

    equation1 :: Int -> Int -> Int
    equation1 x y = (x-y)*(x-y)
    rela :: Int -> [Int] -> [Int]
    rela x [] =[]
    rela x (y:ys) = [ equation1 x y | y <- ys ]