"GEOFFREY ROMER" < GEOFF.ROMER%40GMAIL.COM">GEOFF.ROMER
GMAIL.COM> WRITES:
> ON 5/6/07, JON HARROP < JON%40FFCONSULTANCY.COM">JON
FFCONSULTANCY.COM> WROTE:
>>
>> ACTUALLY, NO. YOU CAN CREATE MUTUALLY RECURSIVE VALUES IN OCAML. FOR EXAMPLE,
>> A PAIR OF MUTUALLY CYCLIC IMMUTABLE LISTS:
>>
>> # LET REC A = 1::B AND B = 2::A;;
>> VAL A : INT LIST = [1; 2; 1; 2; ...]
>> VAL B : INT LIST = [2; 1; 2; 1; ...]
>
> OK, FAIR ENOUGH, BUT THIS APPROACH DOESN'T SEEM LIKE IT GENERALIZES
> WELL TO ARBITRARY LINKAGE PATTERNS; IT ONLY WORKS WHEN YOU'VE GOT ALL
> THE MUTUALLY LINKED PIECES OF DATA 'IN HAND' IN SOME LOCAL CONTEXT,
> SUCH THAT YOU CAN BIND NAMES TO ALL OF THEM WITHIN A SINGLE SCOPE.
THERE IS ALSO AN APPROACH USING LAZY VALUE TO HAVE NON MUTABLE CYCLIC
VALUE THAT ARE MORE COMPLEX AND DYNAMIC THAN THE JON HARROP EXAMPLE.
YOU COULD LOOK TO MY KMP IMPLEMENTATION FOR LIST THAT ONE COULD FIND
THERE :
HTTP://REMI.VANICAT.FREE.FR/OCAML/
THE FIRST ONE (KMP_LIST.ML) USE MUTABILITY TO BUILD THE AUTOMATA
THE SECOND ONE (KMP_LIST_LAZY.ML) USE LAZY VALUE FOR THE SAME THING.
ANOTHER SIMPLER EXAMPLE COULD BE:
TYPE 'A CYCLIC_LIST =
CONS OF 'A * 'A CYCLIC_LIST LAZY.T
LET MAKE_CYCLIC_LIST LI =
LET REC HELPER LI BEG =
MATCH LI WITH
| [] -> LAZY.FORCE BEG
| A::REST ->
CONS (A, LAZY (HELPER REST BEG)) IN
MATCH LI WITH
| [] -> FAILWITH "CANNOT BUILD CYCLIC LIST FROM EMPTY LIST"
| A::REST ->
LET REC CLI =
LAZY (CONS (A, LAZY (HELPER REST CLI))) IN
LAZY.FORCE CLI
LET HEAD (CONS(X, _)) = X
LET TAIL (CONS(_, R)) = LAZY.FORCE R
--
RéMI VANICAT
.