Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map applied to multiple arguments in Haskell

Is there a way to use Haskell's "map" or something similar with multiple arguments?

i.e. to find the distance between a given point (defined as a tuple) and a list of other points:

map distance (-3,-3) buildings

Clearly, that doesn't work, because it tries to map "distance" to (-3,-3), where distance expects two tuples:

let distance pointA pointB = sqrt ( (frst pointB - frst pointA) * (frst pointB - frst pointA) + (scnd pointB - scnd pointA) * (scnd pointB - scnd pointA) )

distance takes two points as arguments: one is (-3,-3) in this example, and one is selected from the list "buildings".

(-3,-3) is just an example. This will have to be a variable; it can't be hardcoded into the function.

Maybe this will make a little more sense:

buildings = [(3,-2),(2,1),(5,3),(4,3),(4,-1)]

firstDiff pointA pointB = subtract ( fst pointA ) ( fst pointB )

secondDiff pointA pointB = subtract ( snd pointA ) ( snd pointB )

distance pointA pointB = sqrt ( (firstDiff pointA pointB) * (firstDiff pointA pointB) +     (secondDiff pointA pointB) * (secondDiff pointA pointB))

--- What I need to happen here is a list "score" to be created by taking all distances from a point in a list lPoints to a point in list buildings.
like image 469
Jason B Avatar asked Mar 01 '10 21:03

Jason B


People also ask

Can map take multiple arguments?

map function only supports mapping functions that have a single argument. This means that if you want to map over a function which expects multiple arguments you can't use it. Instead, you can use Pool.

How many arguments can be passed to map () function?

The map function has two arguments (1) a function, and (2) an iterable. Applies the function to each element of the iterable and returns a map object.

How does map work in Haskell?

map takes a function and a list and applies that function to every element in the list, producing a new list.

What does NS mean in Haskell?

The sequence (n:ns) is a shorthand for head - tail. Quite literally, the first value, the head, is called n and the remained are the other, potentially plural, n s, which is why it is called ns . Haskell has pattern matching.


3 Answers

allDistances src dests = map (\point -> distance src point) dests

allDistances src dests = map (distance src) dests

allDistances src = map (distance src)

allDistances = map . distance
like image 106
ephemient Avatar answered Nov 02 '22 04:11

ephemient


you want:

map (distance (-3, -3)) buildings

which is

map f buildings 
  where f = distance (-3, -3)  
like image 42
ja. Avatar answered Nov 02 '22 06:11

ja.


After seeing the comment on ja's response I'm guessing you wish to use zipWith

Prelude>:type zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]

The documentation states:

zipWith generalises zip by zipping with the function given as the first argument, instead of a tupling function. For example, zipWith (+) is applied to two lists to produce the list of corresponding sums.

So in your code above this could look like:

Prelude> let dist a b = sqrt ( (fst b - fst a) * (fst b - fst a) + (snd b - snd a) * (snd b - snd a) )
Prelude> let buildings = [(1.0,1.0 ), (3.0,3.0 ), (4.0,4.0)]
Prelude> let points = [ (1.2, 2.23), (2.23, 34.23), (324.3, 34.3) ]
Prelude> zipWith dist points buildings
[1.2461540835707277,31.239491032985793,321.7299799521332]
like image 2
Bas Bossink Avatar answered Nov 02 '22 06:11

Bas Bossink