In OCaml, if I have to write a function using many if-then-else, below is my stupid and ugly solution.
let foo () =
let a1 = ... in
if (a1) then
result1
else
let a2 = ... in
if (a2) then
result2
else
let a3 = ... in
if (a3) then
result3
else
let a4 = ... in
if (a4) then
result4
else
result5.
How to beautify the code above? I like C/C++ & Java style which use "return" to save indentation of next if-statement.
Can I do the same thing with OCaml?
int foo () = {
bool a1 = ...;
if (a1)
return result1;
bool a2 = ...;
if (a2)
return result2;
bool a3 = ...;
if (a3)
return result3;
bool a4 = ...;
if (a4)
return result4;
return result5;
}
There is no return statement in OCaml, though you can emulate one with the help of exceptions:
exception Ret of t
let my_ret x = raise (Ret x)
let foo () =
try
let a1 = ... in
if a1 then my_ret result1;
let a2 = ... in
if a2 then my_ret result2;
...
with Ret x -> x
Another helpful solution would be to use lazy evaluation:
let foo () =
let a1 = lazy ...
and a2 = lazy ...
and a3 = lazy ...
in
match a1, a2, a3 with
| lazy true, _, _ -> result1
| _, lazy true, _ -> result2
| _, _, lazy true -> result3
| _, _, _ -> result4
This is one of the examples using lazy, there probably are more concise way of expressing your calculation.
Core library provides a with_return function, that allows you to do a non-local exists from function:
open Core_kernel.Std
let foo () = with_return (fun goto ->
if a1 then goto.return 1;
if a2 then goto.return 2;
if a3 then goto.return 3;
if a4 then goto.return 4;
if a5 then goto.return 5;
return 6)
But generally it is better to use pattern-matching or to rethink your code. For example, if you have a list of predicates, and depending on what predicate is true you want to return a value, that means that you can encode this as a search in some mapping structure:
let foo () = [
clause1, expr1;
clause2, expr2;
clause3, expr3;
] |> List.Assoc.find true
|> Option.value ~default:expr4
Of course in this case you do not have short-circuit evaluation. You can fix this with lazy evaluation or with thunks. But unless your computations is really heavy or produce side-effects, its not worth it.
The if syntactic constructs indeed don't work the same way in C and OCaml. In C, if syntax forms are statements, in OCaml they are expressions. The closest you get in C to OCaml if is the ?: ternary operator. If you try to rewrite your C code using this operator instead of if, you will face the same challenge. That doesn't mean it's impossible however, as other answers give you solutions.
The simplest one, which works in both languages, is to cut your function body in several sub functions (*), and use continuations:
let rec foo () =
let a1 = … (* computation *) in
if a1
then result1
else foo2 ()
and foo2 () =
let a2 = … in
if a2
then result1
else foo3 ()
and foo3 () = … (* etc *)
It may still be a little cumbersome when writing object methods, but you can always use inner functions to regain "indentation balance" within the method scope.
Also note that the rec keyword is there for the sole purpose of allowing each continuation to follow its caller in the source layout, there's no real recursion here.
(*): #gsg also mentioned it in the comments.
Unlike if expressions, match clauses extend to the end of the function even if they contain multiple statements, without needing brackets. So you can do:
let foo () =
match ... with
| true -> result1
| false ->
match ... with
| true -> result2
| false ->
match ... with
| true -> result3
| false ->
match ... with
| true -> result4
| false -> result5
You didn't show where result1 comes from in your example, so I can't be sure, but you might find it's better to have the ... return an option with the result rather than a bool, e.g.
let foo () =
match ... with
| Some result1 -> result1
| None ->
...
Related
I want to write a function prefix_action with seq (resp suffix_action), here is the code in BatEnum :
let prefix_action f t =
let full_action e =
e.count <- (fun () -> t.count());
e.next <- (fun () -> t.next ());
e.clone <- (fun () -> t.clone());
f ()
in
let rec t' =
{
count = (fun () -> full_action t'; t.count() );
next = (fun () -> full_action t'; t.next() );
clone = (fun () -> full_action t'; t.clone() );
fast = t.fast
} in t'
I want to know as we don't have clone in sequences, i want to know how i should considerate clone in these case (is it a use of the sequence) and if that's the case how can we have the number of times that the sequence is used?
Prefix_action Documentation
The sequence as it is defined don't have clone function just because it is "defined by default".
type 'a node =
| Nil
| Cons of 'a * 'a t
and 'a t = unit -> 'a node
As you can see it's just a function returning some sum type, simple value if you wish, there is no side effects (in fact they can be hiden in the body of the function, but for now let me trick you). Thus the clone function in this case is just an identity:
let clone s = s
Now if you look at the definition of enumeration you will notice little mutable keyword:
type 'a t = {
mutable count : unit -> int;
mutable next : unit -> 'a;
mutable clone : unit -> 'a t;
mutable fast : bool;
}
If we try to use same clone as for sequences, we will notice that the changes of one copy will affect the other:
# let e1 = { fast = true; (* ... *) };;
val e1 : 'a t = {fast = true; (* ... *)}
# let e2 = clone e1;;
val e2 : 'a t = {fast = true; (* ... *)}
# e1.fast <- false;;
- : unit = ()
# e2;;
'a t = {fast = false; (* ... *)}
That's why they need clone function.
So now you can implement your functions, for example prefix_action.
prefix_action f e will behave as e but guarantees that f () will be
invoked exactly once before the current first element of e is read.
The problem is in this "exactly once". I'm not sure what does it means, but let say that this means that if you pass sequence to prefix_action f and then two times to hd, then f will be executed only once (because if it means something different it's not interesting). And now we can return to this "side effects" story. Clearly, we can't implement prefix_action without them. The type of sequence doesn't contain any mutable keyword, but it contains functions! Hence, we can wrap our side effect into the function.
let prefix_action : (unit -> unit) -> 'a t -> 'a t = fun f s ->
let b = ref true in
fun () -> (if !b then f (); b := false); s ()
But now, as we have side effects, we need redefine clone. From the specification of prefix_action:
If prefix_action f e is cloned, f is invoked only once, during the
cloning.
Hence our clone:
let clone s = let _ = s (); s
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
I'm not familiar with OCaml, but have been involved in analysing some OCaml code.
This piece of code puzzles me. What is the correct grouping, based on operator precedence?
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
(fmt,
fun () ->
Format.pp_print_flush fmt ();
let s = Buffer.contents b in
Buffer.reset b;
s
)
There are three operators here: ";", "," and "fun". Based on the reference manual the precedence
order is comma > semicolon > fun, which I believe leads to the following groupings below.
Which one is picked by the OCaml compiler? Or is there another grouping that is the correct one?
grouping 1:
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
((fmt,
fun () ->
Format.pp_print_flush fmt ());
(let s = Buffer.contents b in
Buffer.reset b;
s)
)
grouping 2:
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
(fmt,
(fun () ->
Format.pp_print_flush fmt ();
let s = Buffer.contents b in
(Buffer.reset b;
s))
)
For what it's worth, there is another operator used in the code. It's represented by no symbols: the operation of applying a function to a value in OCaml is represented by juxtaposition. This operator has higher precedence than the others.
This code
fun () -> a ; b
parses as
fun () -> (a; b)
not as
(fun () -> a) ; b
It follows because as you say ; has higher precedence than fun (though this terminology is a little suspect).
Similarly
let c = d in e; f
parses as
let c = d in (e; f)
not as
(let c = d in e); f
So, the final expression parses like this:
(fmt,
fun () -> (Format.pp_print_flush fmt ();
let s = Buffer.contents b in
(Buffer.reset b; s))
)
grouping 2 is the correct one.
If you are unsure about how things are parsed, editor helpers may help you (sometimes): ocaml-mode or tuareg-mode (and probably other editor helpers) should give you auto-indentations corresponding with how the code is parsed:
let new_fmt () =
let b = new_buf () in
let fmt = Format.formatter_of_buffer b in
( fmt,
fun () ->
Format.pp_print_flush fmt ();
let s = Buffer.contents b in
Buffer.reset b;
s
)
The identation of let s = ... is below fun () -> which means that that part is within fun () -> .... If it were outside of fun () -> it should be indented differently, in the same level of fun () ->.
Another, very precise but probably over complex way is to examine how the code is parsed directly by ocamlc -dparsetree source.ml.
The doc of Lazy.lazy_from_val states that this function is for special cases:
val lazy_from_val : 'a -> 'a t
lazy_from_val v returns an already-forced suspension of v This is for special purposes only and should not be confused with lazy (v).
Which cases are they talking about?
If I create a pair of suspended computation from a value like:
let l1 = lazy 123
let l2 = Lazy.lazy_from_val 123
What is the difference between these two? Because Lazy.lazy_is_val l1 and Lazy.lazy_is_val l2 both return true saying that the value is already forced!
The special purpose would be if you need a lazy value but you sometimes have an already computed (non-lazy) value. You can use lazy_from_val to turn an already computed value into a (forced) lazy version of your value.
let f lazyint =
Lazy.force lazyint + 42
let li = lazy 4;;
# f li;;
- : int = 46
# f 14;;
^^
Error: This expression has type int but an expression was expected of type
int Lazy.t = int lazy_t
# f (Lazy.lazy_from_val 14);;
- : int = 56
In this (contrived) example, you might wish to call f with an ordinary integer value (14, in this example). You can do it, but you need to use Lazy.lazy_from_val to make it work.
The key difference is that lazy takes an expression of type 'a and creates a suspended computation (in essence, a closure) of type 'a lazy_t. Lazy.lazy_from_val takes a pre-computed value of type 'a and converts it to a (pre-forced) value of type 'a lazy_t. If the expression has side-effects, the difference between the two can be seen.
# let p () = print_string "here\n"; 3 ;;
val p : unit -> int = <fun>
# let l1 = lazy (p ());;
val l1 : int lazy_t = <lazy>
# let l2 = Lazy.lazy_from_val (p ());;
here
val l2 : int Lazy.t = lazy 3
# f l1;;
here
- : int = 45
# f l2;;
- : int = 45
#
You could implement lazy operations directly using explicit closures and references. As Matthias Benkard points out, OCaml's lazy mechanism uses special syntax to make it less cumbersome to work with. I.e., lazy is an OCaml keyword, not a function.
lazy_from_val is a function rather than syntax. Thus,
# let id = fun x -> x;;
val id : 'a -> 'a = <fun>
# Lazy.lazy_is_val (lazy (id 123));;
- : bool = false
# Lazy.lazy_is_val (Lazy.lazy_from_val (id 123));;
- : bool = true
In Javascript there is a pattern called the Russian doll pattern (this may also be called a 'one-shot'). Basically, it's a function that replaces itself with another at some point.
Simple example:
var func = function(){
func = function(){ console.log("subsequent calls call this...");};
console.log("first call");
}
So the first time you call func it'll output "first call" and the next (and subsequent times) it's print "subsequent calls call this...". (this would be easy to do in Scheme as well, for example)
I've been puzzling on how to do this in Ocaml?
Edit: one solution I've come up with:
let rec func = ref( fun () -> func := ( fun () -> Printf.printf("subsequent..\n"));Printf.printf("First..\n"));;
Called as:
!func () ;;
Interestingly, if I do not include the 'rec' in the definition, it never calls the subsequent function... It always prints 'First...'.
yzzlr answer is very good, but two remarks:
It forces the input of the functions to be of type unit. You can use a polymorphic version:
let doll f1 f2 =
let rec f = ref (fun x -> f := f2; f1 x) in
(fun x -> !f x);;
You can do without the hairy recursion:
let doll f1 f2 =
let f = ref f1 in
f := (fun x -> f := f2; f1 x);
(fun x -> !f x);;
(Replacing recursion with mutation is a common trick; it can actually be used to define fixpoints without using "rec")
It's pretty straightforward, but you need to use side-effects. Here's a function that takes two thunks as arguments, and returns a new thunk that calls the first thunk the first time, and the second thunk every other time.
let doll f1 f2 =
let f = ref f1 in
(fun () ->
let g = !f in
f := f2;
g ())
This isn't quite optimal, because we'll keep on overwriting the ref with the same value over and over.
Here's a slightly better version, which uses a recursive definition.
let doll f1 f2 =
let rec f = ref (fun () -> f := f2;f1 ()) in
(fun () -> !f ())
So, now, you'll get this:
# let f = doll (fun () -> 1) (fun () -> 2);;
val f : unit -> int = <fun>
# f ();;
- : int = 1
# f ();;
- : int = 2