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 integerx
and a list of integers. It returns a similar list, but where each elementy
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 ]
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]
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.
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-)
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