Pregunta

I have a list of int ref's my function takes. How could I increment the int at the head of the list, then recurse on the tail? Can ML do multiple lines per function (it seems like I can only do one statement (like if..else..) and write other clauses/code under that without getting an error).

¿Fue útil?

Solución

It would really help if you provided more information, but I can at least explain how the general idea works.

ML uses the ; character to build a single expression out of two. Given two expressions, e1 and e2, you can create the expression (e1 ; e2) (Parentheses not optional -- it won't work without them), which will evaluate everything in e1 and then e2, and has the same value as e2, if e2 has a value.

This is a bit abstract, so here are a few examples:

val a_ref = ref 0;
fun f x = (x := !x + 1; !x);
f a_ref;

This will set the value in a_ref to 1, and then return that value.

Keeping the same ref, but defining a new function:

fun g x = (x := !x + 1; x := (if !x == 2 then 0 else 1); 42);
g a_ref;

This will first increment the value in a_ref (to 2), then check that it equals 2, and so set it to zero, and then return 42.

Hopefully these sort of help your understanding of how ; works.

Now, going on to what you actually seem to want:

Given a list l, if you want to do something to every element of the list, you could try using app. For example:

app (fn x => x := !x + 1) l;

will increment each of the refs in the list.

Alternately, if you want to use recursion,

fun f [] = []
  | f (x::xs) = (x := !x + 1; x::(f xs))

This will increment each of the refs and then return the list. If you instead don't want to return the list,

fun f [] = ()
  | f (x::xs) = (x := !x + 1; f xs);

is another option, that will give unit instead.

If you want to do something more complicated than just incrementing every element, the arguments to f can be changed as suitable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top