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)
Related
I am trying to use propositional logic on a list of values. I will have a list of true or false values. I have a logical expression and I am trying to apply it to a list of values. For example, the logical expression T ^ F v T ^ T will be applied to a list of values(true and false).I will be substituting my values with the T and F in the logical expression. So a list of [true ,true ,false , false] when the expression is applied to it will be like "true ^ true v false ^ false". I will have different combination of the list of values.
fun take(a::b::c::d::rest) =
(a andalso b) orelse (c andalso not d);
(*Test *)
take([false , false , true, false]);
val it = true : bool
The function works but I am wondering if I can use recursion instead to apply the logical expression to the list.
I'm starting to learn OCaml, and I don't understand why this loops indefinitely:
let x = true in
while x do
print_string "test";
x = false;
done;;
What am I missing?
One reason to study OCaml is to learn how to compute with immutable values. Here's a version that doesn't depend on a mutable variable:
let rec loop x =
if x then
begin
print_string "test";
loop false
end
in
loop true
The trick is to reimagine the mutable values as function parameters, which allows them to have different values different times.
It's because OCaml let bindings are immutable. This exact issue is discussed in detail in the ocaml.org tutorial. Use a ref instead, and set and get the value it holds using ! and :=:
let x = ref true in
while !x do
print_string "test";
x := false
done;;
It's best to run ocaml with warnings and strict sequence on to detect problems. e.g.
$ ocaml -strict-sequence -w A
OCaml version 4.01.0
# let x = true in
while x do
print_string "test";
x = false;
done;;
Error: This expression has type bool but an expression was expected of type
unit
This shows the problem: x = false is testing whether x is false or not, not doing an assignment.
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;
I'm wondering how can I build a function in Ocaml that uses List.fold_left to find out if an element exists in a list.
Example:
exists 3 [1;2;3;4;5]
=> true
The type of this function is: a -> bool -> 'a list -> bool
My idea how to do it is as follows:
let exists k l = List.fold_left( fun a x-> a=x) k l
but obviously is wrong. Any suggestion how to do it?
let exists k l =
List.fold_left (fun b x -> b || x = k) false l
Two comments on #tonio's answer:
Use || instead of superfluous if ... then true else ....
Use structural equality (=) instead of reference equality (==) for comparing values.
Moreover, exists is available in List module. The built-in function is more efficient since it doesn't have to go through the whole list every time.
You should use something like
let exists k l =
List.fold_left(
fun a x -> if x == k then true else a)
false l
;;
You have an initial value of false, and pass it while iterating over the list. Once the searched element is found, set the value to true, and pass it along. If the element in the list is not what you search, pass the value you had as input: it is either the initial false, or true if the element you search for has already been found.
after the hints taken by the answers i could be able to improve it more.
Here is my solution
let exists' f l =List.fold_left(fun a b-> f b || a ) false l;;
Like this, this function is more abstract and can be used for any predicate f.
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