Objectif
Le but est de calculer des expressions arithmétiques telles que (X + Y )^2 + (X - Z)*4, ou (cos 4) + (sin 2).
Pour cela if faut définir le type expression Expr. Celui ci peut être composé de constantes (1.6, 2.4,-5,-2.3) de variables (que l on peut nommer x,y,teta,omaga), et bien sur d opérations arithmétiques.
Les opérations arithmétiques peuvent prendre deux arguments, comme c est le cas de la multiplication, l'addition, la soustraction, la division.
type Bin = Plus
| Moins
| Fois
| Div
| Puiss
Ou n'avoir qu'un seul argument comme c'est le cas des fonctions trigonométriques (cosinus, sinus, tangente).
type Trigo = Cos
| Sin
| Tan
Au final on obtient le type algébrique suivant :
type Expr a = OpeBin { bin : Bin , exprg : Expr a, exprd : Expr a}
| Const Float
| Inconnue a
| OpeTrigo { trigo : Trigo, expr : Expr a}
type Var = X
| Y
| Z
Définir les opérations
Les opérations seront définies selon ce modèle
plus : Expr a -> Expr a -> Expr a
plus g d = OpeBin { bin = Plus , exprg = g , exprd = d }
Ou :
cosinus : Expr a -> Expr a
cosinus g = OpeTrigo { trigo = Cos , expr = g }
Evaluation
Il faut ensuite pouvoir évaluer une expression en une liste de points.
Par exemple : X^2 + Y^2 en (X,Y) = (2,3)
evalFold : List (a, Float) -> Expr a -> Expr a
evalFold liste expr0 =
let
eval : (a,Float) -> Expr a -> Expr a
eval (var,val) exprE =
case exprE of
Const a -> Const a
Inconnue xy-> if (xy == var) then Const val
else Inconnue xy
OpeBin { bin,exprg,exprd}-> OpeBin{bin = bin, exprg = eval (var , val) exprg ,exprd = eval (var, val) exprd }
OpeTrigo { trigo , expr } ->OpeTrigo {trigo = trigo, expr = eval (var,val) expr}
in List.foldl eval expr0 liste
Calcul
Il ne reste plus qu'a la calculer :
calcul : Expr a -> Float
calcul expr0 =
case expr0 of
Const a -> a
Inconnue xy-> 0
OpeBin { bin,exprg,exprd} ->
case bin of
Plus -> ( calcul exprg ) + ( calcul exprd)
.
.
.
OpeTrigo { trigo , expr } ->
case trigo of
Cos -> cos (calcul expr )
.
.