Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file roman_num.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111moduleRoman=struct(* Roman module courtesy of Nathan Mishra Linger, as posted on Caml List. *)(****************************************************************************)(* arabic <== roman *)exceptionBadNumeralofcharleteval=function|'I'->1|'V'->5|'X'->10|'L'->50|'C'->100|'D'->500|'M'->1000|c->raise(BadNumeral(c))letarabic(x:string):int=letn=String.lengthxinletrecloopivp=ifi<nthenletc=eval(String.getxi)inloop(i+1)(ifp<cthenv-pelsev+p)celsev+pinifn>0thenletv=eval(String.getx0)inloop10velse0(****************************************************************************)(* (arabic ==> roman) abstract interpretation on SIZES *)letnumerals_size=7letdigit_size=function|0->0|1->1|2->2|3->3|4->2|5->1|6->2|7->3|8->4|9->2|_->assertfalseletreccount_sizek=function|(0,_)->k|(n,j)->ifj>=3thencount_size(digit_size(nmod10)+k)(n/10,j-2)elsen+kletroman_sizen=ifn<0then0elsecount_size0(n,numerals_size)(****************************************************************************)(* arabic ==> roman *)exceptionNegativeletnumerals=['I';'V';'X';'L';'C';'D';'M']letroman(n:int):string=letsize=roman_sizeninletx=String.makesize'M'inlet(++)ck=Bytes.setxkc;k-1inletdigitdonefivetenk=matchdwith|0->k|1->one++k|2->one++(one++k)|3->one++(one++(one++k))|4->one++(five++k)|5->five++k|6->five++(one++k)|7->five++(one++(one++k))|8->five++(one++(one++(one++k)))|9->one++(ten++k)|_->raiseNegativeinletreccountk=function|0,_->()|_,[_]->()|n,(one::five::((ten::_)asnext))->count(digit(nmod10)onefivetenk)(n/10,next)|_->assertfalseincount(size-1)(n,numerals);xend(******************************************************************************)(* Following is by Ashish Agarwal, which just wraps above functions to
provide API following Biocaml's conventions. Only real deviation is
that in above [roman 0] returns empty string instead of an
error. Below, we explicitly disallow 0.
*)openRomantypet=intletof_romans=tryOk(arabic(String.uppercases))withBadNumeralc->error"invalid char in Roman numeral"csexp_of_charletof_arabici=ifi>0thenOkielseerror"invalid non-positive Roman numeral"isexp_of_intletto_roman=romanletto_arabic=Fn.id