Haskell Quad类型Poly实例面积计算错误求助:结果恒为0
问题诊断与修正方案
你的代码存在多处关键错误,导致计算结果始终为0,下面逐一拆解问题并给出修复方案:
1. 直接导致结果为0的核心错误
你在公式里使用了sin(pi),而三角函数sin(π)的结果是0——不管前面的乘积项是多少,乘以0后最终结果必然为0。公式里的θ是两条对角线的实际夹角,不是固定的π值。
2. 对角线长度计算完全错误
两点(x1,y1)和(x3,y3)的距离(对角线d1)正确公式是sqrt((x3 - x1)^2 + (y3 - y1)^2),但你写的sqrt(x3-x1)^2*(y3-y1)^2完全偏离:
- 错误地把横纵坐标的平方项相乘(应该是相加)
- 做了
sqrt(a)^2的无用操作(等价于直接取a,前提a非负)
3. 数据类型构造器不匹配
你定义的四边形类型构造器是MQuad,但在实例实现里用了Quad,这会直接导致编译错误——Haskell找不到Quad这个构造器。
4. 缺少夹角θ的计算逻辑
公式A = ½·d1·d2·sinθ里的θ需要通过对角线向量计算:
- 先得到两条对角线的向量:
(x3-x1, y3-y1)和(x4-x2, y4-y2) - 通过向量点积计算夹角的余弦值,再推导正弦值:
sinθ = sqrt(1 - cosθ²)
修正后的完整代码
先补充你代码里缺失的Point类型定义,再修复所有错误:
-- 补充Point类型定义 data Point = Point Float Float deriving Show class Poly p where area_q :: p -> Float data Quad = MQuad{ qP1 :: Point, qP2 :: Point, qP3 :: Point, qP4 :: Point} deriving Show instance Poly Quad where area_q (MQuad (Point x1 y1) (Point x2 y2) (Point x3 y3) (Point x4 y4)) = let -- 两条对角线的向量分量 dx1 = x3 - x1 dy1 = y3 - y1 dx2 = x4 - x2 dy2 = y4 - y2 -- 计算对角线长度d1、d2 d1 = sqrt (dx1^2 + dy1^2) d2 = sqrt (dx2^2 + dy2^2) -- 向量点积 dotProduct = dx1 * dx2 + dy1 * dy2 -- 计算sinθ,处理对角线为0的边界情况(防止除以0) magProduct = d1 * d2 sinTheta = if magProduct == 0 then 0 else sqrt (1 - (dotProduct / magProduct)^2) in 0.5 * d1 * d2 * sinTheta
测试示例
用一个对角线长4和6、夹角90度的菱形(理论面积12)测试:
testQuad :: Quad testQuad = MQuad (Point 0 0) (Point 2 3) (Point 4 0) (Point 2 (-3)) main = print $ area_q testQuad -- 输出约12.0
内容的提问来源于stack exchange,提问作者user20541711
相关产品推荐
相关产品推荐

