You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中判断四点是否构成正方形的isSquare函数实现问题

Hey there! Let's work through fixing your square-detection function in Haskell. Your initial thought to use distances is a solid starting point, but it misses a few critical details that are tripping you up—let's break this down clearly.

The Problem With Your Initial Approach

Checking if all pairwise distances are equal only works if all four points are identical (which definitely isn't a square!). A valid square has two distinct pairwise distances:

  • 4 instances of the side length (between adjacent vertices)
  • 2 instances of the diagonal length (between opposite vertices)
    Plus, the diagonal length squared should be exactly twice the side length squared (thanks to the Pythagorean theorem: (d^2 = s^2 + s^2 = 2s^2)).

A Robust Solution

We can avoid floating-point precision issues entirely by working with distance squared instead of actual distances. Here's how to implement this:

First, import Data.List for sorting (we'll need it to group our distances):

import Data.List (sort)

Next, write a helper function to calculate the squared distance between two points:

distanceSquared :: (Num a, Ord a) => (a,a) -> (a,a) -> a
distanceSquared (x1, y1) (x2, y2) = (x1 - x2)^2 + (y1 - y2)^2

Now, build the isSquare function. We'll generate all unique pairwise distances, sort them, and verify they match the pattern we expect for a square:

isSquare :: (Num a, Ord a) => (a,a) -> (a,a) -> (a,a) -> (a,a) -> Bool
isSquare p1 p2 p3 p4 = 
  let points = [p1, p2, p3, p4]
      -- Generate all unique pairwise squared distances (6 total for 4 points)
      dists = sort [ distanceSquared a b | a <- points, b <- points, a < b ]
  in case dists of
       -- Check for 4 equal side lengths, 2 equal diagonals, valid proportions, and no overlapping points
       [sideSq, sideSq, sideSq, sideSq, diagSq, diagSq] -> sideSq > 0 && diagSq == 2 * sideSq
       -- Any other pattern means it's not a square
       _ -> False

Why This Works

  • No floating points: Using squared distances avoids precision errors that come with square roots.
  • Handles any vertex order: Since we check all pairwise distances, the input order of the four points doesn't matter.
  • Eliminates edge cases: We explicitly check that sideSq > 0 to rule out overlapping points, and verify the diagonal/side proportion to avoid mistaking rhombuses or other quadrilaterals for squares.

Example Tests

To confirm it works, try these cases:

-- A square with side length 1
isSquare (0,0) (0,1) (1,1) (1,0) -- Returns True

-- A rhombus that's not a square
isSquare (0,0) (1,2) (3,2) (2,0) -- Returns False

-- Four identical points
isSquare (5,5) (5,5) (5,5) (5,5) -- Returns False

内容的提问来源于stack exchange,提问作者mathandtic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:59:29