I have defined a couple of types in my Purescript file:
data Point = Point {
x :: Int,
y :: Int
}
data Rect = Rect {
upperLeft :: Point,
upperRight :: Point,
lowerLeft :: Point,
lowerRight :: Point
}
Now I would like to define a function to check whether two rectangles overlap:
rectsOverlap :: Rect -> Rect -> Boolean
rectsOverlap r s = (r.upperLeft.x > s.lowerRight.x && r.upperLeft.y > s.lowerRight.y)
|| (r.upperLeft.x < s.lowerRight.x && r.upperLeft.y < s.lowerRight.y)
|| (r.lowerLeft.x > s.upperRight.x && r.lowerLeft.y > s.upperRight.y)
|| (r.lowerLeft.x < s.upperRight.x && r.lowerLeft.y < s.upperRight.y)
However, this results in the following error:
Could not match type
{ upperLeft :: { x :: t0
| t1
}
| t2
}
with type
Rect
while checking that type Rect
is at least as general as type { upperLeft :: { x :: t0
| t1
}
| t2
}
while checking that expression r
has type { upperLeft :: { x :: t0
| t1
}
| t2
}
while checking type of property accessor r.upperLeft
while checking type of property accessor (r.upperLeft).x
in value declaration rectsOverlap
where t0 is an unknown type
t1 is an unknown type
t2 is an unknown type
From what I understand from this message, the compiler is inferring some kind of union type where x is t0 | t1, and upperLeft could also have type t2. When I remove my type annotation the compiler infers the following type for this function:
rectsOverlap :: forall t45 t49 t52 t59 t72 t76 t81 t85 t87 t94.
Ord t52 => Ord t59 => Ord t59 => Ord t87 => Ord t94 => Ord t87 => Ord t94 => { upperLeft :: { x :: t52
, y :: t59
| t45
}
, lowerLeft :: { x :: t87
, y :: t94
| t81
}
| t72
}
-> { lowerRight :: { x :: t52
, y :: t59
| t49
}
, upperRight :: { x :: t87
, y :: t94
| t85
}
| t76
}
-> Boolean
So apparently it's inferring a more general type than my Rect type. But I only want a narrowly defined function. If anyone could shed some light on what is going on here, I would really appreciate it.