0

I'm taking a MOOC (no credit). One of the assigned problems is to write a factorial function using a function that follows this:

(’a->’a)->(’a->bool)->’a->’a

I've created that function:

fun do_until (f, g) = fn x => case g(f x) of
              false => f x
            | _ => do_until(f,g) (f x);

but I've had difficulty using my do_until function to implement factorial.

The solution should follow this format I believe:

fun factorial x = (do_until (f, g)) x

The problem I see is that the 'g' function can only validate the result, and if validated, then return that result. Since the function type descriptors are fairly restrictive, it limits you from passing in a tuple to g, then verifying off part of the tuple and returning the other part. ie. (factorial, int to mult) then g would verify from #2 and return #1. Unfortunately the types prevent that. I'm starting to think using do_until as a helper function is impossible unless you compute the factorial some other way and then 'g' would just compare your result to that. Please let me know if I'm wrong and where to go next!

poopsmith
  • 21
  • 1
  • 3

1 Answers1

0

You have the wrong type – the function should be curried – and you will probably have more luck if you give the parameters more descriptive names than "f" and "g":

fun do_until next done x = if done x 
                           then x
                           else do_until next done (next x) 

Note that you can pass anything from factorial to do_until – for instance a tuple that holds your computation state – and then "take it apart" once do_until is done. (I suspect that this is why you're stuck.)

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • yes thank you! this is what I ended up doing. I used a let expression to pass in a tuple that kept track of the state. I'm not sure if its possible without doing that because the 'done' function would have to check given only the partially completed factorial – poopsmith Jul 20 '19 at 01:01
  • @poopsmith If you write a tail recursive factorial, or a loop, you also need two explicit elements in the state (i.e. a counter and the product). If you write a non-tail recursive factorial, it looks like you only need the counter, but the product part of the state isimplicit in the suspended recursive calls. – molbdnilo Jul 20 '19 at 09:47