Reputation: 19
I need to make a function that given natural number n, calculates the product of the numbers below n that are not divisible by 2 or by 3 im confused on how to use nested functions in order to solve this problem (also new to sml ) here is my code so far
fun countdown(x : int) =
if x=0
then []
else x :: countdown(x-1)
fun check(countdown : int list) =
if null countdown
then 0
else
Upvotes: 1
Views: 254
Reputation: 16115
Using the standard library, a function that produces the numbers [1; n-1],
fun below n = List.tabulate (n-1, fn i => i+1);
a function that removes numbers divisible by 2 or 3,
val filter23 = List.filter (fn i => i mod 2 <> 0 andalso i mod 3 <> 0)
a function that calculates the product of its input,
val product = List.foldl op* 1
and sticking them all together,
val f = product o filter23 o below
This generates a list, filters it and collapses it. This wastes more memory than necessary. It would be more efficient to do what @FPstudent and @coder do and generate the numbers and immediately either make them a part of the end product, or throw them away if they're divisible by 2 or 3. Two things you could do in addition to this is,
Make the function tail-recursive, so it uses less stack space.
Generalise the iteration / folding into a common pattern.
For example,
fun folditer f e i j =
if i < j
then folditer f (f (i, e)) (i+1) j
else e
fun accept i = i mod 2 <> 0 andalso i mod 3 <> 0
val f = folditer (fn (i, acc) => if accept i then i*acc else acc) 1 1
This is similar to Python's xrange.
Upvotes: 2
Reputation: 841
It is not clear from the question itself (part of an exercise in some class?) how we are supposed to use nested functions since there are ways to write the function without nesting, for example like
fun p1 n =
if n = 1 then 1 else
let val m = n - 1
in (if m mod 2 = 0 orelse m mod 3 = 0 then 1 else m) * p1 m
end
and there are also many ways to write it with nested functions, like
fun p2 n =
if n = 1 then 1 else
let val m = n - 1
fun check m = (m mod 2 = 0 orelse m mod 3 = 0)
in (if check m then 1 else m) * p2 m
end
or
fun p3 n =
let fun check m = (m mod 2 = 0 orelse m mod 3 = 0)
fun loop m =
if m = n then 1 else
(if check m then 1 else m) * loop (m + 1)
in loop 1
end
or like the previous answer by @coder, just to give a few examples. Of these, p3
is somewhat special in that the inner function loop
has a "free variable" n
, which refers to a parameter of the outer p3
.
Upvotes: 2