I am new to SML.
How do I use the AND operator inside IF statements?
Here is my code:
val y = 1;
val x = 2;
if (x = 1 AND y = 2) then print ("YES ") else print("NO ");
My error is:
stdIn:66.9-67.3 Error: unbound variable or constructor: AND
stdIn:66.3-67.9 Error: operator is not a function [literal]
operator: int
in expression:
1
stdIn:66.3-67.9 Error: operator and operand don't agree [literal]
operator domain: bool * bool
operand: bool * int
in expression:
x = (1 ) y = 2
Thank you
There is no AND operator in SML (unless you define one yourself). There is an and keyword, but you can't use it inside if statements (or generally as a part of any expression) because it's not an operator. It's used in combination with fun to define mutually recursive functions.
You're probably looking for the andalso operator, which takes two boolean operands and returns true if and only if both operands are true.
May I disagree with Vishal's comment?
*-true andalso true ;
val it = false : bool
-true andalso false ;
val it = false : bool*
I think (and so does the REPL) that
true andalso true ;
evaluates to true, not false
here is an example which will clear the usage of andalso
-true andalso true ;
val it = false : bool
- true andalso false ;
val it = false : bool
one and one in digital gates is always 1; therefore
in the above case true andalso true "must necessarily evaluate to true , not false; am'i correct ?
also 1 and 0 can't never be 1;
1 or 0 can be 1;
Related
I got some issue with my code I don't understand. Why did I get this error: This expression has type bool but an expression was expected of type unit. Here is the code
let well_formed (_dimension : int) (_initial1 : _ list)
(_initial2 : _ list) : bool =
if List.length _initial1 + List.length _initial2 != 4 * _dimension then false
else if List.length _initial1 != List.length _initial2 then false
else
let c = 0 in
for i = 1 to _dimension do
let liste =
List.filter (fun x -> x == i) _initial1
# List.filter (fun x -> x == i) _initial2
in
if List.length liste == 4 then c = c + 1 else c = c
done;
if c == _dimension then true else false
I reformated your code, actually for loop have no impact on your code.
let well_formed dimension initial1 initial2 =
let ll1 = List.length initial1 in
let ll2 = List.length initial2 in
let total_list_length = ll1 + ll2 in
if total_list_length != (4 * dimension) then false else
if ll1 != ll2 then false else
let c = 0 in
(* this code do nothing : what is expected ?
for i = 1 to dimension do
let liste = (List.filter(fun x -> x == i) initial1 )#(List.filter(fun x->x == i) initial2) in
if ( List.length liste ) == 4 then c = c+1 else c = c
done;
*)
if c == dimension then true else false
You need to learn imperative features of ocaml if you want to write code this way.
For example c = c + 1 return false
if you want to increment a variable you need to create a ref variable.
OCaml is not C/Python/Javascript, in particular
x = x + 1
means the same as
x == x + 1
in C or Python, i.e., it is a comparison operator. The == operator is the physical comparison (the same as === in Javascript).
Also, integers in OCaml are immutable, so if you want to have a mutable number you need to wrap it in a reference and use := for assignment, e.g.,
let x = ref 0 in
for i = 0 to 5 do
x := !x + 2
done
I am new to SML. I tried to create and test the following function below, but I received an error. I do not know what is the problem.
fun isOld(pFirstTuple: int*int*int, pSecondTuple: int*int*int) =
if (#1 pFirstTuple) < (#1 pSecondTuple)
then
true
if (#1 pFirstTuple) = (#1 pSecondTuple)
then
if (#2 pFirstTuple) < (#2 pSecondTuple)
then
true
else
false
I have tried this command "val p = isOld((8,9,10),(10,11,12))", but it showed me the following error Unbound variable or constructor. How do I fix this?
Here's what your code looks like, stripped down by ignoring various subexpressions (replacing them with A, B, and C)
if A
then true
if B
then if C
then true
else false
You're making extensive use of if/then/else, but the syntax is not quite correct. In SML, every if must have both a then and else clause associated with it. Here's my guess at what you actually meant:
if A
then true
else if B
then if C
then true
else false
else false
This is starting to get quite messy---but you can clean it up with boolean logic. Notice, for example, that if X then true else false means exactly the same thing as simply writing X, because both expressions are type bool and will always evaluate to the same boolean, regardless of what X is. You can extend this reasoning to see that
if X then true else Y is equivalent to X orelse Y.
if X then Y else false is equivalent to X andalso Y.
With these ideas, we can clean up your code considerably:
A orelse (B andalso C)
I have a function that return [[]], and I want to test the result as unit test.
But I found that the expression [[]] == [[]] return false.
Here a simple test code:
# [[]] == [[]];;
- : bool = false
Can someone explain me why this expression is evaluated as false?
Thanks.
Use = since you have structural equality for comparing two values:
# [[]] = [[]];;
- : bool = true
Because == is reference equality, it only returns true if you refer to the same memory location:
let a = [[]]
let b = a
# b == a;;
- : bool = true
The == operator in OCaml means "physical equality". However, you have two (physically) different lists. Probably, you want "structural equality", which is tested by =.
I want to make a if condition like this:
if
((head(c) = 1) or (head(c) = ~1) or (head(c) = ~5) or (head(c) = ~17) or (head(c) = 0))
count +1
else..
the function head return 'a;
It gives me the next error: operator is not a function [tycon dismatch]
operator: bool
in expression
What is the problem? thank you.
I think it's called orelse in SML.
It's called orelse, not just or and andalso instead of and. But orelse and andalso are not functions. Citation from Programming in Standard ML '97:
Note in particular that andalso and orelse are not infix functions because they are not strict in their second argument—that is, they do not always force the evaluation of their second argument—and such functions cannot be defined in a strict programming language such as Standard ML. Thus we cannot apply the op keyword to andalso or orelse.
For this example, you could also write:
let val h = head c in
if List.exists (fn x => x = h) [1, ~1, ~5, ~17, 0]
then count + 1
else ...
end
It seems to be an equivalency comparison for some types, but not strings.
# 3 != 3;;
- : bool = false
# 3 != 2;;
- : bool = true
This is as expected.
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
Why does "odp" != "odp" evaluate to true? What is it actually doing? Shouldn't it generate a type error?
you have experienced the difference between structural and physical equality.
<> is to = (structural equality) as != is to == (physical equality)
"odg" = "odg" (* true *)
"odg" == "odg" (* false *)
is false because each is instantiated in different memory locations, doing:
let v = "odg"
v == v (* true *)
v = v (* true *)
Most of the time you'll want to use = and <>.
edit about when structural and physical equality are equivalent:
You can use the what_is_it function and find out all the types that would be equal both structurally and physically. As mentioned in the comments below, and in the linked article, characters, integers, unit, empty list, and some instances of variant types will have this property.
The opposite for != operator is == operator, not the = one.
# "a" != "a" ;;
- : bool = true
# "a" == "a" ;;
- : bool = false
The == operator is a "physical equality". When you type "a" == "a", you compare two different instances of strings that happen to look alike, so the operator returns false. While having one instance makes it return true:
# let str = "a"
in str == str ;;
- : bool = true
# let str = "a"
in str != str ;;
- : bool = false
A quick explanation about == and != in OCaml in addition to all the correct answers that have already been provided:
1/ == and != expose implementation details that you really don't want to know about. Example:
# let x = Some [] ;;
val x : 'a list option = Some []
# let t = Array.create 1 x ;;
val t : '_a list option array = [|Some []|]
# x == t.(0) ;;
- : bool = true
So far, so good: x and t.(0) are physically equal because t.(0) contains a pointer to the same block that x is pointing to. This is what basic knowledge of the implementation dictates. BUT:
# let x = 1.125 ;;
val x : float = 1.125
# let t = Array.create 1 x ;;
val t : float array = [|1.125|]
# x == t.(0) ;;
- : bool = false
What you are seeing here are the results of an otherwise useful optimization involving floats.
2/ On the other hand, there is a safe way to use ==, and that is as a quick but incomplete way to check for structural equality.
If you are writing an equality function on binary trees
let equal t1 t2 =
match ...
checking t1 and t2 for physical equality is a quick way to detect that they are obviously structurally equal, without even having to recurse and read them. That is:
let equal t1 t2 =
if t1 == t2
then true
else
match ...
And if you keep in mind that in OCaml the “boolean or” operator is “lazy”,
let equal t1 t1 =
(t1 == t2) ||
match ...
They are like two "Tom"s in your class! Because:
In this case, "odp" = "odp"
because they are TWO strings with SAME VALUE!!
So they are not == because they are TWO different strings store in different (Memory) location
They are = because they have the identical string value.
One more step deeper, "odp" is anonymous variable. And two anonymous variable leads to this Two strings.
For your convenience:
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
ints are the only type where physical and structural equality are the same, because ints are the only type that is unboxed