I want to write a function in SML that checks if the parameters a
, b
, c
are true
and, if they are, increases the value x
with 1.0
, 2.0
or 3.0
.
For Example:
fun calc(a:bool, b:bool, c:bool, d:int) =
let
val x = 0.0
in
if a then x+1.0 else x+0.0
;if b then x+2.0 else x+0.0
;if c then x+3.0 else x+0.0
;if d<120 then x+4.0 else x+0.0
end
If I run this code with a
, b
and c
true
and d < 120
, then I get the output:
val it = 0.0 : real
but I want to get as output x
.
First of all, there is no problem with having multiple if
expressions in a single function definition. For example, the following is unproblematic:
fun sign x = if x < 0 then ~1
else if x = 0 then 0
else 1;
Note that if ... then ... else
is an expression which yields a value, not a control structure. You have several independent if
expressions in that in
block, separated by semicolons. When you have several expressions in such an in
block, they are evaluated sequentially, with the result of the last expression being the overall value of that block. This only makes sense when the earlier expressions have side effects (e.g. printing something to the terminal or modifying the store using a ref
variable). In your cases, your expressions have no side effects and you are simply discarding the values (except the very last one).
You seem to want to have a series of val bindings, where the later ones depend on the earlier ones. This can be done, but it would need to be in the let
part of the construct rather than in the in
part. Something like:
fun calc(a:bool, b:bool, c:bool, d:int) =
let
val x = 0.0
val x = if a then x+1.0 else x
val x = if b then x+2.0 else x
val x = if c then x+3.0 else x
in
if d<120 then x+4.0 else x
end
For example:
- calc(false,false,true,119);
val it = 7.0 : real
You can do this more directly by writing a helper function:
fun f(a,x) = if a then x else 0.0;
And then:
fun calc(a,b,c,d) =
let
val x = f(a,1.0) + f(b,2.0) + f(c,3.0)
in
if d < 120 then x + 4.0 else x
end