I wrote a function which works as expected but i don't understand why the output is like that.
Function:
datatype prop = Atom of string | Not of prop | And of prop*prop | Or of prop*prop;
(* XOR = (A And Not B) OR (Not A Or B) *)
local
fun do_xor (alpha,beta) = Or( And( alpha, Not(beta) ), Or(Not(alpha), beta))
in
fun xor (alpha,beta) = do_xor(alpha,beta);
end;
Test:
val result = xor(Atom "a",Atom "b");
Output:
val result = Or (And (Atom #,Not #),Or (Not #,Atom #)) : prop
This is just an output restriction (yes, it's confusing) - by default the depth of value printouts in the top-level (interactive shell) is limited to a fairly small number (i.e. 5). The skipped parts are printed with #.
You can override this depth - at least, in SML-NJ - with printDepth variable:
Control.Print.printDepth := 1024;
P.S. By the way, you don't need a separate do_xor and local function here - just
fun xor(alpha, beta) = Or(...);
will do.
Related
I have been trying to create a cycle to call an changing function i-times , but for some reason the cycle itself always spits out an error. I have also tried an recursive function to call itself but didn't work either.
Is it even possible to make it work with for`s.
r is a list of lists.
a and b are two immutable variables.
(List.nth (r) (i)) gives an list.
let rec changing (lista: 'a zlista) (a:int) (b:int) =
match lista with
| Vazio -> failwith "NO"
| Nodo (n, l, r) ->
if a <= n && n <= b then n
else if a < n && b < n then changing l a b
else changing r a b
let rec call_changing (a: int) (b: int) =
for i=0 to ort do
changing (List.nth (r) (i)) (a) (b)
done;;
Changing returns an int, in order to call it in a for loop you have to ignore the result of the function :
for i = 0 to ort do
let _ = changing .... in ()
done
(* Or *)
for i = 0 to ort do
ignore (changing ....)
done
EDIT :
If you want to print the result you can do :
for i = 0 to ort do
Printf.printf "Result for %d iteration : %d\n" i (changing ....)
done
See the Printf documentation for more information
To perhaps generalize on Butanium's answer, OCaml is not a pure functional programming language. It does contain imperative features. Imperative features are all about side-effects. Functions which exist for the purpose of their side-effects on the system (like Printf.printf) by convention return () (the literal for the unit type).
A for loop is an imperative feature. As such, it expects that any expression (or expessions chained with ;) contained within will return unit. If they do not, you will receive warnings.
The for loop expression itself (for ... = ... to ... do ... done) returns unit so the warning can clue you in that any code in the loop which does not have side-effects is inconsequential, and while your code will compile and run, it may not do what you expect.
As a side note, I believe you may be a little overzealous with the parentheses, likely making your code harder to read.
let rec call_changing (a: int) (b: int) =
for i=0 to ort do
changing (List.nth (r) (i)) (a) (b)
done;;
Properly indented and with extraneous parens removed:
let rec call_changing (a: int) (b: int) =
for i=0 to ort do
changing (List.nth r i) a b
done;;
I want to define a function check_char_fun: (char -> 'a) -> (char ->' a) -> bool that, given two functions
on char, return true when both functions are the same (ie, when they are exactly the same behavior on every one of the possible values of a char) and false otherwise.
let check_char_fun f1 f2 =
let aux = true
for i=0 to 255 do
if (f1 (char_of_int i))=(f2 (char_of_int i))
then aux=false;
done;
if aux=true
then true
else false;;
I am learning OCaml, so I don't know what can I do.
You're nearly there:
let check_char_fun f1 f2 =
let aux = ref true in
for i = 0 to 255 do
if (f1 (char_of_int i)) = (f2 (char_of_int i)) then aux := false
else ()
done;
!aux
Unlike the variables in imperative languages, bindings in OCaml are immutable by default. To create a real variable, we create a bool ref which is mutable and can be changed from within the loop.
OCaml does not have a distinction between statements and expressions like the imperative languages: There are only expressions! Thats why you always need the else clause to an if; this ways the resulting expression always returns a value (in both if and else case) the type of which must be the same -- in this case of type unit (the type of the value () -- which would be void in C).
Your code is not very OCaml-like, but thats what I personally love about OCaml: The functional style is not forced down your throat and you can implement algorithms in an imperative style without entering the academic ivory tower.
First, you have to have a definition for what a "behavior" is. If your functions can raise exceptions the problem gets harder. Your code assumes the functions always return a value, which seems like a good simplification for a beginning problem.
You're also using the (somewhat out-of-date) definition of character that OCaml uses, in that codes are limited to the range 0 .. 255. This also seems OK.
So the only problem I see in your code is that you're expecting to be able to change the value of the aux variable. Variables in OCaml are immutable: you can't change the value that they're bound to.
If you want to keep your code mostly as it is, you can change aux so its value is a reference to a bool. Then you can change the boolean value inside the reference (while aux remains bound to the same reference).
To make a reference to a bool and change the value:
# let x = ref true;;
val x : bool ref = {contents = true}
# !x;;
- : bool = true
# x := false;;
- : unit = ()
# !x;;
- : bool = false
(One of the reasons to study OCaml is to learn how to work with immutable values. So I'd suggest looking for other ways to solve the problem that don't require the use of references.)
let rec range i j =
if i > j then [] else i :: (range (i+1) j);;
let check_char_fun f1 f2 =
let lc = List.map char_of_int (range 0 255) in
List.for_all (fun c -> (f1 c) = (f2 c)) lc;;
test:
#let id x =x;;
val id : 'a -> 'a = <fun>
# check_char_fun id id;;
- : bool = true
# check_char_fun id (fun x -> 'a');;
- : bool = false
Or:
exception Fails_in of char;;
let check_char_fun f1 f2 =
let lc = List.map char_of_int (range 0 255) in
List.iter (fun c ->
if (f1 c) <> (f2 c) then raise (Fails_in c)
) lc;;
# try (
check_char_fun id id
) with Fails_in c -> Printf.printf "Diff(%d)(%c)" (int_of_char c) c
;;
- : unit = ()
# try (
check_char_fun id (fun x -> 'a')
) with Fails_in c -> Printf.printf "Diff(%d)(%c)" (int_of_char c) c
;;
Diff(0)()- : unit = ()
The following applies each function to each character value in the 0 .. 255 range and compares their results, but it does not check for cases where a function raises an exception or causes a side effect elsewhere:
open Core.Std
let check_char_fun f1 f2 =
let chars = List.map ~f:char_of_int (List.range 0 256) in
List.for_all ~f:(fun c -> (f1 c) = (f2 c)) chars
Given this following code (which does not work):
fun func() =
val decimal = 0 (* the final result *)
val multiple = 0 (* keeps track of multiples, eg. In XXV, X would be a multiple *)
val current = 0 (* the digit currently being processed *)
val top = 0 (* value of the last element in the list *)
val last_add = 0 (* the last digit that wasn't a multiple, or subtraction operation *)
val last_sub = 0
val problem = 0 (* if value is 1 then there is a problem with the input *)
val myList = [1,2,3,4,5] (* the list has more values *)
val current = tl(myList) (* grab the last element from the list *)
val myList = tl(myList) (* remove the last element from the list *)
val top = tl(myList) (* grab the value at the end of the list *)
while (not(myList = [])) (* run while the list is not empty *)
if ( (not(myList = [])) andalso (current > top))
then
val decimal = decimal + current - top
val last_sub = top;
val myList = tl(myList)
else
if ( (myList = []) andalso (current = top))
then val decimal = decimal + current
val multiple = multiple + 1
else
if (last_sub = current)
then val problem = 1
else
val decimal = decimal + current
val multiple = 0
val last_add = current
This is only a partial code , which doesn't work at the moment , since the val is not
possible within an if statement .
I want to run in a while loop , how can I do that in ML ?
How can I assign and reassign values into variables that were previously declared in ML ?
The val keyword is not possible within the IF condition , so I cannot update the variables , any idea how to solve that ?
Regards
How can I assign and reassign values into variables that were
previously declared in ML ?
You cannot assign to variables after they are declared in ML.
The val keyword is not possible within the IF condition , so I cannot
update the variables , any idea how to solve that ?
Except at the top level, you usually use val and fun inside a let:
let
val x = blah blah
val y = blah blah
fun f x y = blah blah
in
some expression
end
However, note that this creates a new variable (which may hide any existing variable of the same name), which exists inside the scope of the body of the let. As said before, you cannot assign to an existing variable.
I want to run in a while loop , how can I do that in ML ?
You are almost there. The syntax is while condition do ( ... ). But a while loop is useless without mutable state.
If you want mutable state, you can use a mutable data structure. The language provides a simple "mutable cell" called ref: you create it by passing the initial value to the ref function, you get the current value with the ! operator, and you set a new value with the := operator. You also have to remember that if you want to run multiple imperative "statements", you must separate them with the ; operator, and possibly enclose the whole "block" of statements in parentheses due to precedence issues.
But using while loops and mutable state is really not the right way to go here. You are using a functional language, and it would be much better for you to re-write your algorithm to be purely functional. It's not hard to do. You would turn the body of your while loop into a tail-recursive helper function, and the "variables" that change between iterations of the loop would become arguments to this function. Instead of trying to "set" the values of these variables, it would simply recursively call itself with the new values for the next iteration. If it's tail-recursive, it's equivalent to iteration memory-wise.
I want to print a list inside a help function, for debugging purpose. And for some reason it's not printing anything. Does anyone know what's wrong?
Here is some of my code:
local
....
and xx(LparenToken) = "LparenToken"
| xx(RparenToken) = "RparenToken"
| xx(QuoteToken) = "QuoteToken"
| xx(DotToken) = "DotToken"
| xx(VectorToken) = "VectorToken"
| xx(IntToken(a)) = "IntToken"
| xx(CharToken(a)) = "CharToken"
| xx(StringToken(a)) = "StringToken"
| xx(SymbolToken(a)) = "SymbolToken"
| xx(BoolToken(a)) = "BoolToken"
and readList(nil) = []
| readList(lst:SchemeToken list) = (map(print)((map(xx)(lst))); read(getFirstSexpr(lst))::readList(getRestSexpr(lst)))
...
in
some functions..
end
i have tried this also:
and readList(nil) = []
| readList(lst:SchemeToken list) = (print "x"; read(getFirstSexpr(lst))::readList(getRestSexpr(lst)))
it is not printing. i get just the answer:
- Reader.stringToSexpr "#(a b (1 2 3) c)";
val it =
Vector
[Symbol "a",Symbol "b",Pair (Number 1,Pair (Number 2,Number 3)),
Symbol "c"] : Sexpr
I suspect the problem is not with your list printing code - that's going to work fine, provided it is called with some data.
For reference, there's a nicer way to evaluate for effects with lists: List.app : ('a -> unit) -> 'a list -> unit. It's like List.map, but it doesn't construct a list as a return value. Another one you might like is String.concatWith, which often makes printing code easier, e.g.:
print (String.concatWith "\n" (map xx lst))
And as a final note, you've used lots of unnecessary parentheses there in your example code. You rarely need to parenthesise expressions - especially not if there is no function application involves (i.e., writing (lst) or (xx) is always just going to mean lst or xx, and does not resolve any ambiguity (because there is none). Similarly in your patterns, they could just as easily be written (IntToken a) without changing the meaning (and possibly adding to readability).
I wrote a function which works as expected but i don't understand why the output is like that.
Function:
datatype prop = Atom of string | Not of prop | And of prop*prop | Or of prop*prop;
(* XOR = (A And Not B) OR (Not A Or B) *)
local
fun do_xor (alpha,beta) = Or( And( alpha, Not(beta) ), Or(Not(alpha), beta))
in
fun xor (alpha,beta) = do_xor(alpha,beta);
end;
Test:
val result = xor(Atom "a",Atom "b");
Output:
val result = Or (And (Atom #,Not #),Or (Not #,Atom #)) : prop
This is just an output restriction (yes, it's confusing) - by default the depth of value printouts in the top-level (interactive shell) is limited to a fairly small number (i.e. 5). The skipped parts are printed with #.
You can override this depth - at least, in SML-NJ - with printDepth variable:
Control.Print.printDepth := 1024;
P.S. By the way, you don't need a separate do_xor and local function here - just
fun xor(alpha, beta) = Or(...);
will do.