Question

I've been trying to create an ML function (curried) which takes a list of tuples from the form: (predicate, function) and a list and returns the function operation of every elemnt that returned true, i.e for each condition there's a certain function to perform, for instance:

    - map_many [(fn x => x mod 2 = 0, fn x => x*2), (fn x => x mod 3 = 0, fn x => x+5), (fn x => x mod 4 = 0, fn x => x*x)] [1,2,3,4,5,6,7,8,9,10];

val it = [1,4,8,64,5,17,7,256,14,20] : int list

This is what i've been trying to do but it didn't work so well:

fun map_many _ [] = []
  | map_many [] _ = []
  | map_many ((y,z)::ys) (x::xs) =

    if (y(x) = true)
        then z(x)::map_many ys xs
    else
        x::map_many ys xs; 

What am I doing wrong?

Was it helpful?

Solution

This will give your desired output.

fun map_one [] (old,x) = x
  | map_one ((p,f)::fs) (old,x) = 
      if p old
      then map_one fs (old,(f x))
      else map_one fs (old,x)

fun map_many _ [] = []
  | map_many fs (x::xs) = map_one fs (x,x) :: map_many fs xs

Note that map_one uses a tuple int*int to keep track of the old value (which you use in your predicates), and the generated value.


Your code was only using each pair of functions once, and each number once. You were always putting ys and xs into the recursive function, running them down at the same rate, rather than running the first one down, moving down once on the second, then running the first one down again. You were performing max(length(ys),length(xs)) operations, when you wanted to be doing length(ys)*length(xs).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top