haskell 上的点之间的距离
Distance between points on haskell
我是 haskell 的新手,我必须做一个接受列表并递归计算距离的函数。
For example:
distance [(0,0),(2,0),(2,5)]
->7
distance [(1,1),(3,4)]
->3.6055512
我把两点之间的距离设为这样
distance (x1 , y1) (x2 , y2) = sqrt
(x'*x' + y'*y')
where
x' = x1 - x2
y' = y1 - y2
但不知道如何使用可变列表大小,谢谢
我们可以将这个函数重命名为distance2
来指定它计算两点之间的距离:
distance2 :: Floating a => (a, a) -> (a, a) -> a
distance2 (x1 , y1) (x2 , y2) = sqrt (x'*x' + y'*y')
where x' = x1 - x2
y' = y1 - y2
接下来我们可以利用zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
to iterate concurrently over two lists, and apply a function to the elements. Here we iterate over the list, and its tail. This will thus produce a list of distances. We can make use of sum :: (Num a, Foldable f) => f a -> a
来总结这些距离:
distance2 :: Floating a => [(a, a)] -> a
distance [] = 0
distance xa@(_:xs) = sum (zipWith distance2 xa xs)
首先,像@WillemVanOnsem 一样,我将 distance
重命名为 distance2
:
distance2 :: Floating a => (a, a) -> (a, a) -> a
distance2 (x1 , y1) (x2 , y2) = sqrt (x'*x' + y'*y')
where x' = x1 - x2
y' = y1 - y2
接下来,给定一个列表,将其拆分成对的函数:
splitPairs :: [a] -> [(a,a)]
splitPairs (x:y:xs) = (x,y) : (splitPairs (y:xs))
splitPairs _ = error "can’t split into pairs when <2 elements!"
最后,给定一个点列表,将其分成两对,计算每对之间的距离,并将它们相加:
distance :: Floating a => [(a,a)] -> a
distance = sum . map (uncurry distance2) . splitPairs
如果没有递归,最好将 zipWith
和 sum
函数与应用运算符 <*>
.
一起使用
Prelude> :{
Prelude| dist :: Floating a => [(a, a)] -> a
Prelude| dist = sum . (ds <*> tail)
Prelude| where ds = zipWith (\f s -> sqrt ((fst f - fst s)^2 + (snd f - snd s)^2))
Prelude| :}
Prelude> dist [(0,0),(2,0),(2,5)]
7.0
Prelude> dist [(1,1),(3,4)]
3.605551275463989
我是 haskell 的新手,我必须做一个接受列表并递归计算距离的函数。
For example:
distance [(0,0),(2,0),(2,5)]
->7
distance [(1,1),(3,4)]
->3.6055512
我把两点之间的距离设为这样
distance (x1 , y1) (x2 , y2) = sqrt
(x'*x' + y'*y')
where
x' = x1 - x2
y' = y1 - y2
但不知道如何使用可变列表大小,谢谢
我们可以将这个函数重命名为distance2
来指定它计算两点之间的距离:
distance2 :: Floating a => (a, a) -> (a, a) -> a
distance2 (x1 , y1) (x2 , y2) = sqrt (x'*x' + y'*y')
where x' = x1 - x2
y' = y1 - y2
接下来我们可以利用zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
to iterate concurrently over two lists, and apply a function to the elements. Here we iterate over the list, and its tail. This will thus produce a list of distances. We can make use of sum :: (Num a, Foldable f) => f a -> a
来总结这些距离:
distance2 :: Floating a => [(a, a)] -> a
distance [] = 0
distance xa@(_:xs) = sum (zipWith distance2 xa xs)
首先,像@WillemVanOnsem 一样,我将 distance
重命名为 distance2
:
distance2 :: Floating a => (a, a) -> (a, a) -> a
distance2 (x1 , y1) (x2 , y2) = sqrt (x'*x' + y'*y')
where x' = x1 - x2
y' = y1 - y2
接下来,给定一个列表,将其拆分成对的函数:
splitPairs :: [a] -> [(a,a)]
splitPairs (x:y:xs) = (x,y) : (splitPairs (y:xs))
splitPairs _ = error "can’t split into pairs when <2 elements!"
最后,给定一个点列表,将其分成两对,计算每对之间的距离,并将它们相加:
distance :: Floating a => [(a,a)] -> a
distance = sum . map (uncurry distance2) . splitPairs
如果没有递归,最好将 zipWith
和 sum
函数与应用运算符 <*>
.
Prelude> :{
Prelude| dist :: Floating a => [(a, a)] -> a
Prelude| dist = sum . (ds <*> tail)
Prelude| where ds = zipWith (\f s -> sqrt ((fst f - fst s)^2 + (snd f - snd s)^2))
Prelude| :}
Prelude> dist [(0,0),(2,0),(2,5)]
7.0
Prelude> dist [(1,1),(3,4)]
3.605551275463989