Multiple conditions inside single 'if' in SML - sml

How can multiple conditions be specified under single if? For example, consider the following java code snippet:
if(a==1 && a>b){
//statements ;
}
How can above code be written in sml? I know that I can achieve the goal by using two if's but still if there is a method to specify in the way I want, then it will be smooth.

SML's equivalent of && is andalso. For || there is orelse:
if a = 1 andalso a > b
then (* ... *)
else (* ... *)

Related

How can I improve my Haskell code and make it work?

In my code I call the validateFEN function with a FEN String. A Fen string looks like this for example:
",w84,w41,w56,w170,w56,w41,w84,/,,w24,w40,w17,w40,w48,,/,,,w16,w16,w16,,,/,,,,,,,,/,,,,,,,,/,,,,,,,,/,,,b1,b1,b1,,,/,,b3,b130,b17,b130,b129,,/,b69,b146,b131,b170,b131,b146,b69,"
The function should take the string and check if it's a FEN string.
How does it know if it's a FEN string? -> My string has 9 rows and 9 columns. I don't need to check if the pieces (example: w86) are at their right position.
validateFEN' b = help3 (filter (\x -> x == ',' || x == '/' ) b)
help3 b = (if help1 b == True then (if head (drop 8 b) == '/' then help3 (drop 9 b) else False) else False )
help1 b = help2 (take 8 b)
help2 b = foldr (+) 0 (map (\x -> if x == ',' then 1 else 0 )b) == 8
Why do I keep getting the error for a empty list?
Exception: Prelude.head: empty list
I understand that with my code there is no stop. The program doesn't know when the string is "correct".
Is there a shorter simpler way of doing this?
One way to reuse existing library functions to make this clearer would be to use stripPrefix.
help3 s = case stripPrefix ",,,,,,,,/" s of
Nothing -> False
Just s' -> help3 s'
Of course, you still need to handle the final case, where there is no terminating /. This can be done with a single extra clause:
help3 ",,,,,,,," = True
help3 s = {- ... -}
You might want to ponder whether validateFEN' should have a similar special case for the empty string.
BUT I would strongly suggest simply not implementing validateFEN' in the first place. My guess is that the plan is something like this:
Check if a string is valid FEN.
Process the string, assuming FEN-ness.
Instead, I recommend the following approach:
Parse the string into a native data structure that represents the information available in a FEN string.
Process the native structure.
Step 1, if written with standard parsing solutions, will "accidentally" validate the string -- i.e. running your parser will return something like Either Error FEN, which you can pattern match on to either discover that the string is invalid or that it is valid and has been turned into a more idiomatic representation.

How can I check that the length of a list of custom data types in Haskell?

I'm making a simple sudoku program that only utilises a 9 x 9 grid. To that end, I have a function to check it is 9 x 9 and also checks to make sure the inputted values are Just Num's.
Here's the closest solution I've come to, I'm thinking the issue is in the pattern match I think (correct me if I'm wrong), this is because it compiles but has the logical error of returning False not True when given a perfectly fine test case. Anyways, here's the code dump :D
type Cell = Maybe Int
type Row = [Cell]
data Sudoku = Sudoku [Row]
deriving ( Show, Eq )
rows :: Sudoku -> [Row]
rows (Sudoku ms) = ms
isSudoku :: Sudoku -> Bool
isSudoku (Sudoku [[cs]]) = length [cs] == 9 && length cs == 9
isSudoku (Sudoku _) = False
Many thanks in advance for any advice given!
[x] as a pattern will only match a singleton list (list with exactly one element in it).
To perform the nested lists check, do
isSudokuList cs = length cs == ... &&
and [length c == ... | c <- cs]
You will have to tweak it to fit your types of course.
You could also define
niner [a,b,c,d,e,f,g,h,i] = True
.......
and use it.

Should an if statement be associated with else statement in ocaml?

In ocaml, I want to have many nested if statements and a return value on each of the conditions. The code is becoming complicated like this.
let func arg1 arg2 =
if condition1 then arg1+arg2
else
(
//code1
if condition2 then arg1*arg2
else
(
//code2
if condition3 then arg1+arg2
else
(
//code3
)
)
)
Instead of such nested statements can I have code like this?
let func arg1 arg2 =
if condition1 then arg1+arg2
//code1
if condition2 then arg1*arg2
//code2
if condition3 then arg1+arg2
//code3
You can use an if statement without a else if it returns a value of type unit (basically when it only does something).
if condition then print_int 3
However, in your case, you want to return a value of type int and as such the else branch is mandatory. It can nonetheless be shortened using else if statements.
if condition1 then arg1+arg2
else if condition2 then arg1*arg2
else if condition3 then arg1+arg2
else arg1
Note that once again, you need to use else at the end.
Pattern-matching can also be extended to verify some conditions using when clauses:
match 3 with
| 0 -> 0
| 1 -> 1
| x when x mod 2 = 0 -> x/2
| x when x mod 3 = 0 -> x/3
| x -> x
OCaml is a strongly and statically typed language, which means that the type of every expression is checked at compile-time.
Take a look at the following snippet.
if condition then true_value else false_value
During compilation, the type-checker will check for the following:
condition must have type bool;
true_value must have the same type as false_value;
The whole expression has the same type as true_value and false_value.
If any one of these statements is not true, then the compilation fails with a type error.
Now, let's take a look at a if statement, without a else.
if condition then true_value
If the condition is false, then the expression evaluates to (), the only value of type unit. Using statements 2 and 3 from before, the only type that true_value can have here is unit. That means that you can't use int or string or anything as the true_value.
Usually, deeply nested if-else statements is considered a code smell: it may indicate that your code needs refactoring. For instance, OCaml offers pattern-matching. Depending on what your actual code looks like, it may be the way to go.
Just fyi, you don't need all those parentheses. Anything that comes after an else is considered to be a single expression in the 'else' branch. You could write your code like
let func arg1 arg2 =
if condition1 then arg1+arg2 else
(* code1 *)
if condition2 then arg1*arg2 else
(* code2 *)
if condition3 then arg1+arg2 else
(* code2 *)

Error SML: unbound variable or constructor

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)

How should I calculate p times of f(x)?

I want to calculate f(..f(x)) p times. The following is my code.
let rec function f x p = if p = 0 then x else function f (f x) p-1;;
I wonder how I should make it right.
This is very close, but your code has syntax errors that are going to make it hard to make progress. I think the main problem is that you're using function as an identifier, but it is a keyword in OCaml. If you change to myfun, things should start working quite a bit better.
You also need to watch your precedences. The following code:
f a b-1
is parsed like this:
(f a b) - 1
not like this:
f a (b - 1)
You need to write the parentheses explicitly to get this second parse.
You can define a recursive function ch to apply a function f many times (Church numeral??) as follows:
let rec ch f p x = if p = 0 then x else f (ch f (p-1) x);;
The problems in your original code are that:
need to name the function as something, such as ch here.
need to call the same function ch to get the recursion going as shown above. In your original code, there is no recursion.
Example
let p1 x = x + 1 ;;
ch p1 3 1 ;;
this will give you
- : int = 3
as intended.