From 7fc91f883249d6c83ded0563bb7ebaa447291b7c Mon Sep 17 00:00:00 2001 From: Izaak Walton Date: Tue, 15 Oct 2024 11:29:52 -0700 Subject: [PATCH] Add `fromfrac` function for converting fractions to dividable types --- docs/intro-to-coalton.md | 10 ++++++++++ library/math/real.lisp | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/intro-to-coalton.md b/docs/intro-to-coalton.md index f822b4579..0316a8112 100644 --- a/docs/intro-to-coalton.md +++ b/docs/intro-to-coalton.md @@ -548,6 +548,16 @@ All of these cases are sufficiently common that we provide a few shorthands: - `floor/`, `ceiling/`, and `round/` for integer-to-integer division, and +Fractions can be converted to other dividable types using `fromfrac` (Note: This may result in precision loss): + +``` +COALTON-LIBRARY/MATH/REAL> (coalton (the Double-Float (fromfrac 1/2))) +0.5d0 +COALTON-LIBRARY/MATH/REAL> (coalton (the Single-Float (fromfrac 999/1000))) +0.999 +``` + + ## Lists Coalton uses Lisp lists under the hood. Lists can be constructed with `make-list`. diff --git a/library/math/real.lisp b/library/math/real.lisp index e9f5647d6..62ee1ffcb 100644 --- a/library/math/real.lisp +++ b/library/math/real.lisp @@ -31,7 +31,8 @@ #:inexact/ #:floor/ #:ceiling/ - #:round/)) + #:round/ + #:fromfrac)) (in-package #:coalton-library/math/real) @@ -264,7 +265,16 @@ Note: This does *not* divide double-float arguments." (declare round/ (Integer -> Integer -> Integer)) (define (round/ a b) "Divide two integers and round the quotient." - (round (exact/ a b)))) + (round (exact/ a b))) + + (declare fromfrac (Dividable Integer :a => Fraction -> :a)) + (define (fromfrac q) + "Converts a fraction to a target type. + +Specifically, target types must have an instance of `Dividable Integer :a`. + +This conversion may result in loss of fidelity." + (general/ (numerator q) (denominator q)))) #+sb-package-locks (sb-ext:lock-package "COALTON-LIBRARY/MATH/REAL")