(* definição dos tipos de moedas e seus respectivos valores, necessario para o programa *)

  val romannum = 
 [(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), 
  (100, "C"), (90, "XC"), (50, "L"), (40, "XL"), 
  (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")]; 


(********************************************************************************)
(* Retorna o valor em arábico da moeda ao entrar com sua representação romana *)

fun valor (cod,(v,nome)) = if cod=nome then v else 0;


(********************************************************************************)
(* Procura a moeda desejada buscando na lista e descobrindo seu valor *)

fun find (name,nil)=0 | find(name,(a::b))= valor(name,(a))+ find(name,b);


(********************************************************************************)
(* multiplica valor da moeda pela quantidade dessa moeda na carteira *)

fun multicarteira(quant,nome) = quant * find(nome,romannum);


(********************************************************************************)
(* percorre a carteira somando o produto moedas x quant*)

fun somacarteiraA (nil)=0 | somacarteiraA(a::b)= multicarteira(a) + somacarteiraA(b);


(********************************************************************************)
(* transforma um número arábico em seu equivalente romano *)

 fun romano (n : int, []) = []  | romano (n, romans as ((v, nome) :: romanr)) = 
 if n >= v then nome :: romano(n - v, romans) else romano(n, romanr);


(********************************************************************************)
(* transforma o resultado e somacarteira em Romano e concatena a lista em uma string *)

fun somacarteiraR a = concat(romano(somacarteiraA(a),romannum)); 

(*********************************************************************************)

 


(* 
1. Para a utilização do programa definir definir uma lista carteira do tipo :

   val x = [(quantidade de moedas,"simbolo em romano"),..]
 
   EX:  val carteira=[(3,"M"), (4,"IX"), (8,"I"), (5,"V")];  
 
2. Para fazer as operações no programa, devemos chamar as seguintes funções :
   2.1  somacarteiraA(carteira);     (* retorna a soma da carteira em arábico*)
   2.2	somacarteiraR(carteira);     (* retorna a soma da carteira em romano*)  
*)

    Source: geocities.com/br/dchagastelles

               ( geocities.com/br)