if statement checking multiple conditions in SML - sml

I am new to SML and I have written a program that takes 3 integer numbers (n,z,k) and wants to compare them with a value given in the program, if the statement is correct it will return true, else false. conditions and values should be equal simultaneously, I mean program will return true if all these numbers are equal to the value given in the program, so my if statement should check 3conditions at the same time.
my problem is that I don't know how I can write all these 3conditions in one if clause, because SML don't recognize for example & or ^ as and!
for example i want to check whether if(n==8 && k==5 && z==9). what should I use instead of &
here is the code:
fun EvalR (n: int , k: int , z:int) =
if (n=8 ???) then true
else false;

Since Ashkan Parsa referred to the CS317 SML Style Guide, I thought I would point out what you might derive from it.
Let function names start with a lower case, e.g. evalR.
Don't write if ... then true else false; simply write ....
Some disagree; type annotations certainly are helpful, but so is type inference.
As nazila says, the and operator in Standard ML is called andalso.
So,
fun evalR (n, k, z) =
n = 42 andalso k = 43 andalso z = 0
It might seem comfusing that the function body contains =s at the same time as the function being defined with a = to separate the function arguments from the function body. Just think of the latter =s as value operators and the first = as a part of declaring things (like types, values, functions, etc.)

I found it. we can use andalso in SML.

Related

OCaml return value in if statement nested in loop

I am trying to return a value if something occurs when iterating through a list. Is it possible to return a string if X happens when iterating through the list, otherwise return another string if it never happens?
let f elem =
if not String.contains str elem then "false" in
List.iter f alphlist;
"true";
This is not working in my implemented method sadly.
OCaml is a functional language, so you pretty much need to concentrate on the values returned by functions. There are ways to return different values in exceptional cases, but (IMHO) the best way to learn is to start just with ordinary old nested function calls.
List.iter always returns the same value: (), which is known as unit.
For this reason, the expression List.iter f alphlist will also always return () no matter what f does.
There is another kind of list-handling function that works by maintaining a value across all the calls and returning that value at the end. It's called a fold.
So, if you want to compute some value that's a kind of summary of what it saw in all of the string lists in alphlist, you should probably be using a fold, say List.fold_left.
Here is a function any_has_7 that determines whether any one of the specified lists contains the integer 7:
let any_has_7 lists =
let has_7 sofar list =
sofar || List.mem 7 list
in
List.fold_left has_7 false lists
Here's how it looks when you run it:
# any_has_7 [[1;2]; [3;4]];;
- : bool = false
# any_has_7 [[1;2]; [5;7]; [8;9]];;
- : bool = true
In other words, this function does something a lot like what you're asking for. It returns true when one or more of the lists contains a certain value, and false when none of them contains the value.
I hope this helps.

Remove real element from list - SML

I have written the following code:
fun remove_element(nil, elem) = raise Empty
| remove_element(hd::tl, elem) = if(hd=elem) then tl else hd::remove_element(tl, elem);
but that function (which removed element elem from list) works for int. I need to make it work for real numbers, but I can't do it. I have tried a lot of ways of rewriting the function and also I used :real but these bring me errors.
Any suggestions?
Thank you
The accepted answer should have allowed you to finish your assignment, so I will show two other approaches for variations of your problem without worrying about doing your homework for you. As Kevin Johnson said, it isn't possible to directly compare two reals. It is possible to do so indirectly since a=b if and only if a<=b and b<=a. Often this is a bug, especially if the list in question is of numbers produced by numerical computations. But -- there are some situations where it makes sense to compare reals for equality so you should certainly be able to do so as long as you are clear that this is what you want. This leads to the following modification of your code:
fun remove_real([],x:real) = []
| remove_real(y::ys,x) =
if (y <= x andalso y >= x) then
remove_real(ys,x)
else
y::remove_real(ys,x);
A few points:
1) I changed it to remove all occurrences of the element from the list rather than just the first occurrence. This involved changing the basis case to returning the empty list since [] with y removed is just [] rather than an error situation. Also, rather than simply returning the tail if the element is found I return the recursive call applied to the tail to remove any additional occurrences later on. You could easily modify the code to make it closer to your original code.
2) I needed to put the explicit type annotation x:real so that SML could infer that the list was of type real list rather than type int list.
3) I replaced nil by [] for aesthetic reasons
4) I replaced your pattern hd::tl by y::ys. For one thing, hd and tl are built-in functions -- I see no reason to bind those identifiers to anything else, even if it is just local to a function definition. For another thing, the less visual clutter in a pattern the better.
5) I made more use of white space. Partially a matter of taste, but I think that fairly complicated clauses (like your second line) should be split across multiple lines.
If you want to go the route of including an error tolerance for comparing reals, I think that it makes most sense to include the tolerance as an explicit parameter. I find |x-y| < e to be more natural than two inequalities. Unfortunately, the built-in abs only applies to ints. If x - y is real then the expression
if x - y < 0.0 then y - x else x - y
returns the absolute value of x - y (it flips the sign in the case that it is neagative). As an added bonus -- the comparison with 0.0 rather than 0 is all that SML needs to infer the type. This leads to:
fun remove_elem([],x,tol) = []
| remove_elem(y::ys,x,tol) =
if (if x - y < 0.0 then y - x else x - y) < tol then
remove_elem(ys,x,tol)
else
y::remove_elem(ys,x,tol);
Typical output:
- remove_real([2.0, 3.1, 3.14, 3.145, 3.14], 3.14);
val it = [2.0,3.1,3.145] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.01);
val it = [2.0,3.1] : real list
- remove_elem([2.0, 3.1, 3.14, 3.145, 3.14], 3.14,0.001);
val it = [2.0,3.1,3.145] : real list
The issue is here: hd=elem
In languages like ML and Javascript, you cannot directly compare two reals as reals are bound to rounding errors.
You have to use a lambda range and define an interval instead. elem - lambda < hd andalso elem + lambda > hd

Ocaml unboud value

I'm trying to write a simple Ocaml function but im getting this error:
Error: This expression has type unit
but an expression was expected of type int
let rec euclid a b =
if a = b then a
else if a < b then 1
else if a > b then 2
To fix the immediate problem, you need else clauses in your function:
let rec euclid a b =
if a = b then a
else if a < b then 1
else 2 (* You know a > b is the only possible alternative *)
You may realize this, but this function is not recursive, nor, I think, is it doing what you want it to do.
However, there is an error in the way you're conceptualizing how a function works in Ocaml. The way you've written the function is imperative in nature; it is a series of if/then statements which are acted upon sequentially. Rather, the return value of euclid should be simply the result of one broad if/then statement (an integer value). Nesting, as I have done above, can be acceptable, but the essential thing to take away is that a function is just a single expression which is evaluated, not a series of imperative actions.
EDIT for updated question:
All OCaml if/then statements should have else clauses. Your very last nested if/then statement has no else clause. If OCaml detects an if/then statement with no else clause, an else clause is assumed returning () (unit). Essentially, if a > b is false, what should OCaml return? It assumes nothing, but returning () conflicts with the supposed type of your function (an integer).
Of course, that a > b is false is impossible in your function, since if not a = b and not a < b, the only other choice is a > b. Thus, you don't need another if statement at the end of your function; at that point, you know without a doubt that a > b, so you can simply say else 2.

Check whether number is Fibonacci or not in Standard ML

I am trying to write a code which checks if number is Fibonacci or not in ML. I am a beginner. Help me find out what is the problem with my code.
fun isfib(n :int): bool=
let
val a1=1;
val a2=1;
val temp=0;
in
while a2<n do (
a1=temp
a2=a1
a2=temp+a2
)
if a2=n then true
else false
end;
a1=temp
a2=a1
a2=temp+a2
= is the equality operator in SML, not an assignment operator. So the above code is just equivalent to this:
false (* because a1 is 1, but temp is 0 *)
true (* because a1 and a2 are both 1 *)
true (* because 1 = 0 + 1 *)
So you have three side-effect-free expressions in your loop, so it just won't do anything.
It's clear that you actually want to change the values of those variables, but you can't do that. Variables in SML are immutable - you can't change them after they're set. So even having a while condition like a2 < n doesn't make sense because a2 and n can't change, so the condition is either always true or always false. If you want to use a while loop like this, you should look into the ref type, which allows you to create mutable values that you can use to simulate mutable variables.
That said using while loops and mutation is not idiomatic SML. There's a reason why variables in SML aren't mutable: the language designers want to encourage you to not rely on mutation (and thus also not on while loops). The idiomatic way to loop in SML is to either use higher order functions (like map, filter, foldl etc.) or recursion. For your problem a recursive function would make the most sense.

WHILE loop for the LIST

I need to write a very simple function in SML. It should check if the value 'elem' is greater than any value of the field 'f1' in the list 'L'. The list 'L' contains 3 fields - 'f1','f2','f3'. The function should return 1 if the statement 'elem>f1' is true for any of the members of the list 'L'. Otherwise, the function should return 0. For instance:
L =
f1 f2 f3
1 4 6
2 1 2
3 4 8
8 5 9
elem = 3
fun check(L: myList, elem: int): int =
let
val counter = ref 0
val counter_end = length L
in
while (!counter <= counter_end) do
let val f1 = List.nth(L,counter)
in
if elem > f1 then 1 else 0
end
counter := !counter + 1
end
I don't know how to get the field 'f1' from the list 'L'. Any ideas are HIGHLY appreciated.
In SML (and functional languages in general), you'll typically want to rely on recursion rather than imperative constructs like loops.
I'm a bit rusty in SML, but here's one way to define the function
fun check elem [] = 0
| check elem ((f1,f2,f3)::tl) = if elem > f1 then 1 else check elem tl;
It can then be called like this:
(* define a list to scan *)
val L = [(1,4,6),(2,1,2),(3,4,8),(8,5,9)];
(* call the function on our list *)
check 3 L;
The function is defined recursively, using pattern matching: The first line says that if the function is called on an empty list, the result is zero.
The second line says that if it is called on a list, where the first element is the tuple (f1,f2,f3), then the result is 1 if elem > f1, and otherwise, it's the result of invoking the function recursively on the tail of the list
Also note that I omitted the type specifiers. You rarely need them, because the language infers the types automatically. The compiler already knows which types can be safely used with the code you wrote, so why bother telling it what types you think the arguments are going to be?
Use a recursive function instead of using a loop. (And it would probably make more sense to use a boolean return instead of an integer.)
Easiest way to extract the fields is via pattern matching in the argument list. Assuming your three fields are in a tuple, something like this:
fun check((f1,f2,f3)::L: myList, elem: int)