! Figure 5.19
module sorts
   public :: operator(/), operator(+), sqrt
   public :: length_by_time, time_plus_time, sqrt_metres_squared
   intrinsic sqrt
   type, public :: time
      real :: seconds
   end type time
   type, public :: velocity
      real :: metres_per_second
   end type velocity
   type, public :: length
      real :: metres
   end type length
   type, public :: length_squared
      real :: metres_squared
   end type length_squared
   interface operator(/)
      module procedure length_by_time
   end interface
   interface operator(+)
      module procedure time_plus_time
   end interface
   interface sqrt
      module procedure sqrt_metres_squared
   end interface
contains
   function length_by_time(s, t) result (res)
      type(length), intent(in) :: s
      type(time), intent(in)   :: t
      type(velocity)           :: res
      res%metres_per_second = s%metres / t%seconds
   end function length_by_time
   function time_plus_time(t1, t2)  result (res)
      type(time), intent(in)   :: t1, t2
      type(time)               :: res
      res%seconds = t1%seconds + t2%seconds
   end function time_plus_time
   function sqrt_metres_squared(l2) result (res)
      type(length_squared), intent(in) :: l2
      type(length)                     :: res
      res%metres = sqrt(l2%metres_squared)
   end function sqrt_metres_squared
end module sorts
