sunrise :: num -> num -> num -> num
|| Earth's spin tilt [in degrees]
|| -> latitude of your favourite location [in degrees]
|| -> time of year [in days]
|| -> sunrise in non-Equation-Of-Time-corrected local mean time [in hours]
||     ie, relative to "altitude-midnight" of that day (when sun is lowest)
  sunrise spin_tilt latitude time_of_year
    = radian_oriented_sunrise
        (spin_tilt / 180 * pi)
        (latitude / 180 * pi)
        ((time_of_year + 11) / 365.25 * 2 * pi)
      / pi * 12


radian_oriented_sunrise :: num -> num -> num -> num
|| Earth's spin tilt [in radians]
|| -> latitude of your favourite location [in radians]
|| -> time of year [in radians from Dec. 21]
|| -> sunrise in non-Equation-Of-Time-corrected local mean time [in radians]
||     ie, relative to "altitude-midnight" of that day (when sun is lowest)
  radian_oriented_sunrise spin_tilt latitude time_of_year
    = pi - arccos (tan effective_spin_tilt * tan latitude)
      where
      effective_spin_tilt = arcsin (sin spin_tilt * cos time_of_year)





hms :: num -> (num, num, num)
|| converts hours to (hours,minutes,seconds)
||  (or indeed degrees to (degrees,minutes,seconds)!!)
  hms h = (h $realdiv 1,
           (h $realmod 1 * 60) $realdiv 1,
           (h $realmod 1 * 60) $realmod 1 * 60)

archms :: (num, num, num) -> num
|| inverse function to hms above
  archms (h,m,s) = h + m/60 + s/3600







|| it would be nicer if Miranda had these built-in, but it doesn't!

tan :: num -> num
  tan x = sin x / cos x

arcsin :: num -> num
  arcsin x = pi/2 * x, if x=1 \/ x=-1
           = arctan (x/sqrt(1-x^2)), otherwise

arccos :: num -> num
  arccos x = pi/2, if x=0
           = arctan (sqrt(1-x^2)/x), if x>0
           = arctan (sqrt(1-x^2)/x) + pi, if x<0

realdiv :: num -> num -> num
  x $realdiv y = entier (x/y)

realmod :: num -> num -> num
  x $realmod y = x - y * (x $realdiv y)
