0
votes

I'm looking for help with a problem. I'm trying to write a function that passes both a list and function in ML. Basically what the program is supposed to do is take a list and run each element through the function. If the function returns true, then the element is added to a list and the list returned once the function has finished executing. Here's my code:

fun select(x:list, funct)=      (* Define a new function that accepts a list and the prime function as a parameter*)
    while (tl(x) not nil) do(       (*While the tail is not empty*)
            if funct(hd(x)) then    (*Then run the function with the the head*)
                    val l = l::hd(x)        (*Adds the head of x to the list *)
            (*else 1+tl(x)*));

Any help would be very much appreciated.

2

2 Answers

4
votes

A few pointers:

  • You pretty much never use loops in ML. Any time you need to iterate, write a recursive function.
  • You rarely need to specify types. In this case ML can infer, from the fact that you're calling tl(x), that x must be a list.
  • Instead of using hd(x) and tl(x) to decompose the list, you generally do this with pattern matching in the function arguments. Instead of a single argument x, write the argument as x::xs; x will be assigned to the head of the list, and xs to the tail.
  • Instead of using conditional statements to check the structure of your argument (in this case, whether your list is empty or not), you can write multiple function definitions with different patterns. ML will try them one by one until it finds one that fits.
  • The body of your function needs to be an expression which evaluates to your return value. Everything in ML is an expression; even if x then a else b is essentially a function which returns either a or b.

Keeping all this in mind, here's something to get you started:

fun select([], funct) = []
|   select(x::xs, funct) = ...

The two cases here replace your while condition - the first will be evaluated only when your list is nil. The pattern in the second case automatically assigns values to the head and tail of your list. This definition is intended to be recursive; select([],funct)=[] is your base case, and select(x::xs,funct)=... should include a call to select(xs,funct).

1
votes

take a list and run each element through the function. If the function returns true, then the element is added to a list and the list returned once the function has finished executing.

This is exactly the built-in List.filter function. No need to reinvent the wheel.