Haskell报错:Ord Pos实例缺失,源于minimum函数使用
Hey there, let's break down why you're hitting this error and how to fix it quickly.
The Root Cause
When you used type Pos = (Int, Int), you weren't creating a new type—just an alias for the existing (Int, Int) tuple. Tuples in Haskell automatically come with Ord instances (since Int is Ord), so minimum had no trouble comparing values.
But when you switched to data Pos = Pos (Int, Int) deriving (Show, Eq), you created a completely new type. You only derived Show and Eq, but not Ord. The minimum function needs to compare elements in your list [(score p, p) | p <- allBlanks puzzle]:
- The first element of each tuple (
score p) is a numeric type with anOrdinstance, so that's fine. - But when two scores are equal, Haskell tries to compare the second element (
p, aPosvalue) to determine which is smaller—and sincePosdoesn't have anOrdinstance, you get that error.
The Fixes
1. Derive the Ord Instance (Simplest Option)
Just add Ord to your deriving clause. Haskell will automatically generate an Ord instance for Pos that compares the underlying (Int, Int) tuple exactly like the original alias did:
data Pos = Pos (Int, Int) deriving (Show, Eq, Ord)
2. Custom Ord Instance (If You Need Specific Behavior)
If you want to define a custom ordering for Pos (e.g., compare x-coordinate first instead of y), you can manually implement the Ord instance:
instance Ord Pos where -- Example: Compare y first, then x (matches the original tuple behavior) compare (Pos (y1, x1)) (Pos (y2, x2)) = compare (y1, x1) (y2, x2) -- Or if you want to compare x first: -- compare (Pos (y1, x1)) (Pos (y2, x2)) = compare (x1, y1) (x2, y2)
Why This Works
With the Ord instance in place, minimum can properly compare the (score p, p) tuples. When scores are equal, it uses your Pos ordering to pick the smallest position, resolving the error.
内容的提问来源于stack exchange,提问作者Vacation

