content: import Control.Monad (join)
  import Data.Bifunctor (bimap)
  import Text.Printf (printf)
  
  type Radians = Float
  
  type Degrees = Float
  
  ---------- ANGLE DIFFERENCE BETWEEN TWO BEARINGS ---------
  
  bearingDelta :: (Radians, Radians) -> Radians
  bearingDelta (a, b) -- sign * dot-product
    =
    sign * acos ((ax * bx) + (ay * by))
    where
      (ax, ay) = (sin a, cos a)
      (bx, by) = (sin b, cos b)
      sign
        | ((ay * bx) - (by * ax)) > 0 = 1
        | otherwise = -1
  
  angleBetweenDegrees :: (Degrees, Degrees) -> Degrees
  angleBetweenDegrees =
    degrees
      . bearingDelta
      . join bimap radians
  
  --------------------------- TEST -------------------------
  main :: IO ()
  main =
    putStrLn . unlines $
      fmap
        ( uncurry (printf "%6.2f° - %6.2f°  ->  %7.2f°")
            <*> angleBetweenDegrees
        )
        [ (20.0, 45.0),
          (-45.0, 45.0),
          (-85.0, 90.0),
          (-95.0, 90.0),
          (-45.0, 125.0),
          (-45.0, 145.0)
        ]
  
  ------------------------- GENERIC ------------------------
  
  degrees :: Radians -> Degrees
  degrees = (/ pi) . (180 *)
  
  radians :: Degrees -> Radians
  radians = (/ 180) . (pi *)
  