datatype unit = Cm | M | Ft | In
val allUnits = Cm :: M :: Ft :: In :: []

type length = {Value : float, Uni : unit}

val show_unit = mkShow (fn u => case u of
                                    Cm => "cm"
                                  | M => "m"
                                  | Ft => "ft"
                                  | In => "in")

val show_length = mkShow (fn {Value = v, Uni = u} => Float.format 3 v ^ " " ^ show u)

fun ratio from to =
    case (from, to) of
        (Cm, Cm) => 1.0
      | (M, M) => 1.0
      | (Ft, Ft) => 1.0
      | (In, In) => 1.0

      | (_, M) =>
        (case from of
             Cm => 0.01
           | M => 1.0
           | In => 0.0254
           | Ft => 0.3048)

      | (M, _) => 1.0 / ratio to from

      | _ => ratio from M * ratio M to

fun convert {Value = v, Uni = u} u' =
    {Value = v * ratio u u', Uni = u'}