intersect package:LambdaHack

The intersect function takes the list intersection of two lists. It is a special case of intersectBy, which allows the programmer to supply their own equality test. For example,
>>> [1,2,3,4] `intersect` [2,4,6,8]
[2,4]
If equal elements are present in both lists, an element from the first list will be used, and all duplicates from the second list quashed:
>>> import Data.Semigroup

>>> intersect [Arg () "dog"] [Arg () "cow", Arg () "cat"]
[Arg () "dog"]
However if the first list contains duplicates, so will the result.
>>> "coot" `intersect` "heron"
"oo"

>>> "heron" `intersect` "coot"
"o"
If the second list is infinite, intersect either hangs or returns its first argument in full. Otherwise if the first list is infinite, intersect might be productive:
>>> intersect [100..] [0..]
[100,101,102,103...

>>> intersect [0] [1..]
* Hangs forever *

>>> intersect [1..] [0]
* Hangs forever *

>>> intersect (cycle [1..3]) [2]
[2,2,2,2...
A pair (a, b) such that a divided by b is the X coordinate of the intersection of a given line and the horizontal line at distance d above the X axis. Derivation of the formula: The intersection point (xt, yt) satisfies the following equalities:
yt = d
(yt - y) (xf - x) = (xt - x) (yf - y)
hence
(yt - y) (xf - x) = (xt - x) (yf - y)
(d - y) (xf - x) = (xt - x) (yf - y)
(d - y) (xf - x) + x (yf - y) = xt (yf - y)
xt = ((d - y) (xf - x) + x (yf - y)) / (yf - y)
General remarks: The FOV agrees with physical properties of tiles as diamonds and visibility from any point to any point. A diamond is denoted by the left corner of its encompassing tile. Hero is at (0, 0). Order of processing in the first quadrant rotated by 45 degrees is
45678
123
@
so the first processed diamond is at (-1, 1). The order is similar as for the restrictive shadow casting algorithm and reversed wrt PFOV. The fast moving line when scanning is called the shallow line, and it's the one that delimits the view from the left, while the steep line is on the right, opposite to PFOV. We start scanning from the left. The PointI (Enum representation of Point) coordinates are cartesian. The Bump coordinates are cartesian, translated so that the hero is at (0, 0) and rotated so that he always looks at the first (rotated 45 degrees) quadrant. The (Progress, Distance) cordinates coincide with the Bump coordinates, unlike in PFOV. Debug: check that the line fits in the upper half-plane.
The intersectBy function is the non-overloaded version of intersect. It is productive for infinite arguments only if the first one is a subset of the second.