使用距离函数确定最接近的一对点,Haskell

问题描述:

我试图弄清楚如何用项目的这个函数得到最接近的一对点。我收到一个我不太明白的错误。谢谢您的帮助。我已经给出了可用的距离公式,我不确定我是否正在使用closestPairs函数正确调用距离函数。使用距离函数确定最接近的一对点,Haskell

type Point a = (a,a) 

-- Determine the true distance between two points. 
distance :: (Real a, Floating b) => Point a -> Point a -> b 
distance (x1,y1) (x2,y2) = sqrt (realToFrac ((x1 - x2)^2 + (y1 - y2)^2)) 

type Pair a = (Point a, Point a) 

-- Determine which of two pairs of points is the closer. 
closerPair :: Real a => Pair a -> Pair a -> Pair a 
closerPair (p1,p2) (q1,q2) | distance (p1, p2) > distance (q1,q2) = (q1,q2) 
          | otherwise = (p1,p2) 

mod11PA.hs:30:30: error: 
* Could not deduce (Real (Point a)) 
    arising from a use of `distance' 
    from the context: Real a 
    bound by the type signature for: 
       closerPair :: Real a => Pair a -> Pair a -> Pair a 
    at mod11PA.hs:29:1-50 
* In the first argument of `(>)', namely `distance (p1, p2)' 
    In the expression: distance (p1, p2) > distance (q1, q2) 
    In a stmt of a pattern guard for 
       an equation for `closerPair': 
    distance (p1, p2) > distance (q1, q2) 

mod11PA.hs:30:30: error: 
* Could not deduce (Ord (Point (Point a) -> b0)) 
    arising from a use of `>' 
    (maybe you haven't applied a function to enough arguments?) 
    from the context: Real a 
    bound by the type signature for: 
       closerPair :: Real a => Pair a -> Pair a -> Pair a 
    at mod11PA.hs:29:1-50 
    The type variable `b0' is ambiguous 
    Relevant bindings include 
    q2 :: Point a (bound at mod11PA.hs:30:24) 
    q1 :: Point a (bound at mod11PA.hs:30:21) 
    p2 :: Point a (bound at mod11PA.hs:30:16) 
    p1 :: Point a (bound at mod11PA.hs:30:13) 
    closerPair :: Pair a -> Pair a -> Pair a (bound at mod11PA.hs:30:1) 
* In the expression: distance (p1, p2) > distance (q1, q2) 
    In a stmt of a pattern guard for 
       an equation for `closerPair': 
    distance (p1, p2) > distance (q1, q2) 
    In an equation for `closerPair': 
     closerPair (p1, p2) (q1, q2) 
     | distance (p1, p2) > distance (q1, q2) = (q1, q2) 
     | otherwise = (p1, p2) 

之所以能够通过改变closerPair的方法,采取点的两个对中来解决我的问题:

closerPair :: Real a => Pair a -> Pair a -> Pair a 
closerPair ((x,y),(x1,y1)) ((x2,y2),(x3,y3)) | distance (x,y) (x1,y1) > distance (x2,y2) (x3,y3) = ((x2,y2),(x3,y3)) 
              | otherwise = ((x,y),(x1,y1)) 
+0

'distance'询问**两个'Pair's **,你只喂它**一个**(因为你写'distance(p1,p2)')...所以Haskell“抱怨”你应该给'距离'第二个参数。 –

+0

@WillemVanOnsem距离公式采取两点,一对是2点,所以我很困惑,为什么它的说法呢?我错过了什么/ –

+1

看签名。 '距离::点a - >点a - > ..''(p1,p2)'不同于'p1 p2' – karakfa

你已经贴出了正常工作实施

closerPair ((x,y),(x1,y1)) ((x2,y2),(x3,y3)) 
    | distance (x,y) (x1,y1) > distance (x2,y2) (x3,y3) = ((x2,y2),(x3,y3)) 
    | otherwise = ((x,y),(x1,y1)) 

但请注意,没有原因实际上模式匹配Point在这里协调:你只是把x1,y1x2,y2 ...无论如何。因此,为什么不把它写成

closerPair (p₀,p₁) (p₂,p₃) 
    | distance p₀ p₁ > distance p₂ p₃ = (p₂,p₃) 
    | otherwise      = (p₀,p₁) 

顺便说一句,这可以在标准功能方面来写:

import Data.List (minimumBy) 
import Data.Ord (comparing) 

closerPair v w = minimumBy (comparing $ uncurry distance) [v,w] 
+0

啊,我明白你在说什么,现在变得更有意义。我正在做比我需要的更多的工作。谢谢。 –