我正在编写haskell中的hasrsine公式。 在我的函数的一个版本中,定义和声明如下:
haversine :: Double -> Double -> Double -> Double -> Double
haversine lat1 lon1 lat2 lon2 = let dlon = (toRad lon2) - (toRad lon1)
dlat = (toRad lat2) - (toRad lat1)
a = sin(dlat/2)^2 + cos(lat1)*cos(lat2)*sin(dlon/2)^2
c = 2 * asin(sqrt(a))
in c*r
这个功能很好。当我将声明更改为:
haversine :: (Double a) => a -> a -> a -> a -> a
我收到以下错误:
• Expecting one fewer argument to ‘Double’
Expected kind ‘* -> *’, but ‘Double’ has kind ‘*’
• In the type signature:
haversine :: (Double a) -> a -> a -> a -> a -> a
据我所知,通过编写(Double a),我将标记为'a'的其余参数置于Double类约束中。为什么后一个声明会导致此错误?
答案 0 :(得分:4)
在Haskell中,类型和类是两回事。
有一个名为Double
的类型。
没有名为Double
的类。
此外,类约束必须后跟=>
,而不是->
。
您可以通过类约束变量,例如Eq
,Show
等。如果您希望它是特定的类型 ......好吧,只需写出那种类型而不是变量。
答案 1 :(得分:4)
1)Double a
不是有效约束。您正在寻找Floating a
2)约束在=>
的左侧给出,与->
左侧的函数参数不同。
所以要编译,你的代码应该是
haversine :: Floating a => a -> a -> a -> a -> a
haversine lat1 lon1 lat2 lon2 = let dlon = (toRad lon2) - (toRad lon1)
dlat = (toRad lat2) - (toRad lat1)
a = sin(dlat/2)^2 + cos(lat1)*cos(lat2)*sin(dlon/2)^2
c = 2 * asin(sqrt(a))
in c*r
假设您已全局定义
r :: Floating a => a
toRad :: Floating a => a -> a