2017-03-17 43 views
0

我是Haskell的新手,所以我不太明白這裏發生了什麼,除了它是使用返回值或值的類型錯誤。有人能解釋我做錯了什麼嗎?謝謝。在Haskell中輸入關於Real類型的錯誤

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((x1 - x2)^2 + (y1 - y2)^2) 

* Couldn't match expected type `b' with actual type `a' 
     `a' is a rigid type variable bound by 
     the type signature for: 
      distance :: forall a b. 
         (Real a, Floating b) => 
         Point a -> Point a -> b 
     at mod11PA.hs:12:13 
     `b' is a rigid type variable bound by 
     the type signature for: 
      distance :: forall a b. 
         (Real a, Floating b) => 
         Point a -> Point a -> b 
     at mod11PA.hs:12:13 
    * In the expression: sqrt ((x1 - x2)^2 + (y1 - y2)^2) 
     In an equation for `distance': 
      distance (x1, y1) (x2, y2) = sqrt ((x1 - x2)^2 + (y1 - y2)^2) 
    * Relevant bindings include 
     y2 :: a (bound at mod11PA.hs:13:22) 
     x2 :: a (bound at mod11PA.hs:13:19) 
     y1 :: a (bound at mod11PA.hs:13:14) 
     x1 :: a (bound at mod11PA.hs:13:11 
+0

感謝您的編輯。 –

回答

2

就像是沒有明確的轉換功能,在標準庫數量最多的功能,sqrt返回相同類型它的參數的值:如果用b替換a

GHCi> :t sqrt 
sqrt :: Floating a => a -> a 

,你函數將通過類型檢查器:

distance :: (Floating b) => Point b -> Point b -> b 
distance (x1,y1) (x2,y2) = sqrt((x1 - x2)^2 + (y1 - y2)^2) 

如果您確實需要值爲012的實例的類型在你的論點,你可以使用realToFrac做必要的轉換:

GHCi> :t realToFrac 
realToFrac :: (Real a, Fractional b) => a -> b 
distance :: (Real a, Floating b) => Point a -> Point a -> b 
distance (x1,y1) (x2,y2) = sqrt (realToFrac ((x1 - x2)^2 + (y1 - y2)^2)) 

P.S:需要注意的是RealFloating沒有的類型,但類。例如,我們說,Double是一個具體類型,它有一個Floating類的實例(或者,不那麼正式,DoubleFloating)。

+0

對於這個項目,我們不允許更改方法簽名。所以我必須使用realToFrac?我會在整個線路上打電話給realToFrac嗎? –

+0

@JohnOchs最簡單的方法是將它應用於你給'sqrt'的值。看到我的編輯答案。 – duplode

+0

添加realToFrac使其工作。非常感激。 –