有没有办法使用Haskell的“map”或类似的多个参数?
即。找到给定点(定义为元组)与其他点列表之间的距离:
map distance (-3,-3) buildings
显然,这不起作用,因为它试图将“距离”映射到(-3,-3),其中距离需要两个元组:
let distance pointA pointB = sqrt ( (frst pointB - frst pointA) * (frst pointB - frst pointA) + (scnd pointB - scnd pointA) * (scnd pointB - scnd pointA) )
距离需要两个点作为参数:在本例中,一个是(-3,-3),一个是从“建筑物”列表中选择的。
( - 3,-3)只是一个例子。这必须是一个变量;它不能硬编码到函数中。
也许这会更有意义:
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.
答案 0 :(得分:19)
allDistances src dests = map (\point -> distance src point) dests
allDistances src dests = map (distance src) dests
allDistances src = map (distance src)
allDistances = map . distance
答案 1 :(得分:11)
你想要:
map (distance (-3, -3)) buildings
是
map f buildings
where f = distance (-3, -3)
答案 2 :(得分:2)
在看到对ja回复的评论后,我猜你想使用zipWith
Prelude>:type zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith通过使用作为第一个参数给出的函数进行压缩来进行压缩,而不是使用tupling函数。例如,zipWith(+)应用于两个列表以生成相应总和的列表。
所以在上面的代码中,这可能看起来像:
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]
答案 3 :(得分:0)
distance (x, y) (z, w) = sqrt $ (x - z) ^ 2 + (y - w) ^ 2
func1 = map . distance
func2 starts ends = starts >>= flip func1 ends
func1是你描述的函数,而func2是相似的,但是接受多个起点而不是一个,并找到每个组合与终点之间的距离。
答案 4 :(得分:0)
距离公式很简单:
distance :: Floating a => (a,a) -> (a,a) -> a
distance (x1,y1) (x2,y2) = sqrt $ (x2 - x1)^2 + (y2 - y1)^2
请注意使用模式匹配来分解参数,而不是使用fst
和snd
乱丢代码。
然后
从给定点到列表中所有点的相应距离distanceFrom :: Floating a => (a,a) -> [(a,a)] -> [a]
distanceFrom p = map (distance p)
虽然参数似乎缺失,但在Haskell中称为partial application。在distanceFrom
中,我们有两个:
distance p
是一个点的函数,其值是该点距p
的距离map (distance p)
是一个点列表的函数,其值是这些点与p
的距离尝试将Haskell函数设计为部分应用程序,以便将小函数组合成更大的函数。如ephemient's answer中所述,您可以进一步推进pointfree定义(没有明确的参数) - 更优雅,更先进的风格。
buildings
中距lPoints
中所有点的距离{/ 1}}
main :: IO ()
main = do
mapM_ (putStrLn . unwords . map (printf "%6.3f")) score
where
score = [ distanceFrom x buildings | x <- lPoints ]
例如,使lPoints
和buildings
相等,输出为
0.000 3.162 5.385 5.099 1.414 3.162 0.000 3.606 2.828 2.828 5.385 3.606 0.000 1.000 4.123 5.099 2.828 1.000 0.000 4.000 1.414 2.828 4.123 4.000 0.000
但考虑到所有的冗余,在这种特殊情况下,这有点无聊。要改为打印strict upper triangle,请使用
strictUpperTriangle :: [[a]] -> [[a]]
strictUpperTriangle [] = []
strictUpperTriangle xs = go (init xs)
where go (x:xs) = tail x : map tail (go xs)
go [] = []
printSUT :: PrintfArg a => [[a]] -> IO ()
printSUT sut = putStr (unlines $ map pad sut)
where n = length sut
pad xs = let k = n - length xs in
unwords $ take k blanks ++ map (printf "%*.3f" w) xs
blanks = repeat (take w $ repeat ' ')
w = 6 :: Int
main :: IO ()
main = printSUT tri
where
score = [ distanceFrom x buildings | x <- lPoints ]
tri = strictUpperTriangle score
输出:
3.162 5.385 5.099 1.414 3.606 2.828 2.828 1.000 4.123 4.000