在Haskell中输入关于Real类型的错误

时间:2017-03-17 21:55:45

标签: haskell

我是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((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

1 个答案:

答案 0 :(得分:2)

与标准库中的大多数数字函数一样,它们不是显式转换函数,sqrt返回与其参数类型相同的值:

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

如果您将a替换为b,您的函数将通过类型检查器:

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

如果您确实需要参数中具有Real个实例类型的值,则可以使用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)。< / p>