Code source du site TeacherCorner.lamdera.app, contenant une suite d'outils permettant d'automatiser la production de documents pédagogiques.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
TeacherCorner/src/Fraction.elm

206 lines
4.1 KiB

module Fraction exposing
( Erreur
, Fraction
, Resultat
, asciiMath
, denominateur
, difference
, estEntier
, exp
, fraction
, inverse
, map2
, numerateur
, oppose
, produit
, quotient
, somme
, teX
)
import Arithmetic exposing (gcd)
type alias Fraction =
{ numerateur : Int, denominateur : Int }
type alias Resultat =
Result Erreur Fraction
type alias Erreur =
String
fraction : Int -> Int -> Resultat
fraction a b =
let
min =
1 - 2 ^ 31
max =
2 ^ 31 - 1
in
case b of
0 ->
Err "Division par zéro."
_ ->
if a > max || b > max || a < min || b < min then
Err "Certains calculs font intervenir des valeurs trop grandes pour être prises en charge."
else
Ok <| simplifier <| Fraction a b
simplifier : Fraction -> Fraction
simplifier a =
let
pgcd =
gcd a.numerateur a.denominateur
sgnDuDen =
if a.denominateur < 0 then
-1
else
1
in
{ a
| numerateur = sgnDuDen * (a.numerateur // pgcd)
, denominateur = sgnDuDen * (a.denominateur // pgcd)
}
numerateur a =
a.numerateur
denominateur a =
a.denominateur
estEntier a =
a.denominateur == 1
map2 : (Fraction -> Fraction -> Resultat) -> Resultat -> Resultat -> Resultat
map2 operation resultat1 resultat2 =
case ( resultat1, resultat2 ) of
( Ok fractiontion1, Ok fractiontion2 ) ->
operation fractiontion1 fractiontion2
( Err erreur, _ ) ->
Err erreur
( _, Err erreur ) ->
Err erreur
somme : Fraction -> Fraction -> Resultat
somme a b =
let
pgcd =
gcd a.denominateur b.denominateur
aDenBis =
a.denominateur // pgcd
bDenBis =
b.denominateur // pgcd
in
fraction (a.numerateur * bDenBis + b.numerateur * aDenBis) (a.denominateur * bDenBis)
oppose : Fraction -> Fraction
oppose a =
Fraction -a.numerateur a.denominateur
difference : Fraction -> Fraction -> Resultat
difference a b =
somme a (oppose b)
produit : Fraction -> Fraction -> Resultat
produit a b =
let
pgcd =
gcd a.numerateur b.denominateur
pgcdBis =
gcd b.numerateur a.denominateur
aNum =
a.numerateur // pgcd
aDen =
a.denominateur // pgcdBis
bNum =
b.numerateur // pgcdBis
bDen =
b.denominateur // pgcd
in
fraction (aNum * bNum) (aDen * bDen)
inverse : Fraction -> Resultat
inverse a =
case a.numerateur of
0 ->
Err "Division par zéro"
_ ->
Ok <| Fraction a.denominateur a.numerateur
quotient : Fraction -> Fraction -> Resultat
quotient a b =
Result.andThen (produit a) <| inverse b
exp : Fraction -> Fraction -> Resultat
exp a b =
let
sgnDeA =
if a.numerateur < 0 then
-1
else
1
sgnDeB =
if b.numerateur < 0 then
-1
else
1
in
if b.denominateur == 1 && b.numerateur < 0 then
fraction ((sgnDeA * a.denominateur) ^ (sgnDeB * b.numerateur)) ((sgnDeA * a.numerateur) ^ (sgnDeB * b.numerateur))
else if b.denominateur == 1 then
fraction (a.numerateur ^ b.numerateur) (a.denominateur ^ b.numerateur)
else
Err "L'extraction de racine n'est pas disponible pour les nombres écrits sous forme fractiontionnaire."
teX a =
case a.denominateur of
1 ->
String.fromInt a.numerateur
_ ->
if a.numerateur < 0 then
"-\\fraction{" ++ String.fromInt -a.numerateur ++ "}{" ++ String.fromInt a.denominateur ++ "}"
else
"\\fraction{" ++ String.fromInt a.numerateur ++ "}{" ++ String.fromInt a.denominateur ++ "}"
asciiMath a =
"(" ++ String.fromInt a.numerateur ++ "/" ++ String.fromInt a.denominateur ++ ")"