【问题标题】:Haskell error: Couldn't match type ‘a’ with ‘Double’Haskell 错误:无法将类型“a”与“Double”匹配
【发布时间】:2019-11-29 15:36:45
【问题描述】:

我正在编写一个 Haskell 代码来查找 k 个最近邻居的列表,按照距离顺序,根据度量 d 到点列表 xs 中的点 p。我的代码如下

import Data.List
import Data.Function

type Point a = (a,a)
type Metric a = (Point a) -> (Point a) -> Double

neighbours :: Int -> Metric a -> Point a -> [Point a] -> [Point a]
neighbours k calDistance p [] = []
neighbours k calDistance p ps
 | k < 0     = error "k cannot be negative"
 | otherwise = take k (neighbours' (sortBy (compare `on` snd) [ (poi,dis) | (poi,dis) <- points p ps]))

neighbours' :: [(Point a, Double)] -> [Point a]
neighbours' xs = [ x | (x,y)<-xs]

points :: Point a -> [Point a] -> [(Point a, Double)]
points _ [] = []
points p1 (p2:px) = (p2,(calDistance p1 p2)): points p1 px

calDistance :: Metric Double
calDistance (x1,y1) (x2,y2) = sqrt((x1-x2)**2 + (y1-y2)**2)

错误是

    • Couldn't match type ‘a’ with ‘Double’
      ‘a’ is a rigid type variable bound by
        the type signature for:
          points :: forall a. Point a -> [Point a] -> [(Point a, Double)]
        at A4.hs:27:1-53
      Expected type: Point Double
        Actual type: Point a
    • In the first argument of ‘calDistance’, namely ‘p1’
      In the expression: (calDistance p1 p2)
      In the first argument of ‘(:)’, namely ‘(p2, (calDistance p1 p2))’
    • Relevant bindings include
        px :: [Point a] (bound at A4.hs:29:15)
        p2 :: Point a (bound at A4.hs:29:12)
        p1 :: Point a (bound at A4.hs:29:8)
        points :: Point a -> [Point a] -> [(Point a, Double)]
          (bound at A4.hs:28:1)
   |
29 | points p1 (p2:px) = (p2,(calDistance p1 p2)): points p1 px
   |     

但是,如果我将“Metric Double”更改为“Double a”,也会出现编译错误:无法将预期类型“Double”与实际类型“a”匹配。谁能告诉我怎么解决?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    见于执行

    points :: Point a -> [Point a] -> [(Point a, Double)]
    

    你打电话

    calDistance :: Metric Double
    

    这意味着a 必须是Double,如果有人调用points 并以Point Int 类型的值作为第一个参数会发生什么? calDistance 应该如何处理,因为它只能处理 Point Double 的值?

    错误告诉您,calDistance 被调用时使用了 Point a 类型的值,其中 a 可以是任何类型。这不匹配,因为 calDistance 期望 Point Double 作为它的第一个参数。

    【讨论】:

    • 进一步a一般;并非所有类型都支持sqrt**。正确的签名(如果您完全省略签名,GHCi 可以为您推断)是Floating a =&gt; Metric a
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-21
    • 2014-10-17
    相关资源
    最近更新 更多