2017-03-17 113 views
0

我試圖弄清楚如何用項目的這個函數得到最接近的一對點。我收到一個我不太明白的錯誤。謝謝您的幫助。我已經給出了可用的距離公式,我不確定我是否正在使用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

回答

1

你已經貼出了正常工作實施

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

啊,我明白你在說什麼,現在變得更有意義。我正在做比我需要的更多的工作。謝謝。 –