I have the following code written in Ocaml to try and generate the first 50 catalan numbers:
let rec f n:int64=
if n<1 then 1L
else (4*n-2)*f((n-1L))/(n+1L)
;;
for i = 0 to 50 do
Printf.printf "%d\n"(f i)
done;
But the problem is that the recursion function doesn't seem to accept Int64 values and seems to want Int instead despite me notating n as int64:
File "/proc/self/fd/0", line 3, characters 19-21:
3 | else (4*n-2)*f((n-1L))/(n+1L)
^^
Error: This expression has type int64 but an expression was expected of type
int
exit status 2
Is there a way to ensure I can int64 numbers here with recursion?
Your problem isn't recursion per se, it's that the operators in OCaml are strongly typed. So the - operator is of type int -> int -> int.
Without getting into lots of fussing with the syntax, the easiest fix is probably to use the named functions of the Int64 module. You can use Int64.sub rather than -, for example.
You can use the notation Int64.(... <expr> ...) to avoid repeating the module name. If you rewrite your code this way, you get something like this:
let rec f (n : int64) : int64 =
Int64.(
if n < 1L then 1L
else
mul (sub (mul 4L n) 2L)
(f (div (sub n 1L) (add n 1L)))
)
Looking at the results computed by this function, they don't look like Catalan numbers to me. In fact the 50th Catalan number is too large to be represented as an int64 value.
So there is still some work to do. But this is how to get past the problem you're seeing (IMHO).
If you really want to work with such large numbers, you probably want to look at the Zarith module.
Submitted as an additional suggestion to Jeffrey's answer: whether using Int64 or Zarith, you might create a module defining arithmetic operators and then locally open that to clean up your code.
E.g.
module Int64Ops =
struct
let ( + ) = Int64.add
let ( - ) = Int64.sub
let ( * ) = Int64.mul
let ( / ) = Int64.div
end
let rec f n =
Int64Ops.(
if n < 1L then 1L
else (4L * n - 2L) * f (n - 1L) / (n + 1L)
)
Or you could use a functor to make it easier to work with multiple different types of numbers.
module type S =
sig
type t
val add : t -> t -> t
val sub : t -> t -> t
val mul : t -> t -> t
val div : t -> t -> t
end
module BasicArithmeticOps (X : S) =
struct
type t = X.t
let ( + ) = X.add
let ( - ) = X.sub
let ( * ) = X.mul
let ( / ) = X.div
end
# let module A = BasicArithmeticOps (Float) in
A.(8. + 5.1);;
- : float = 13.1
# let module A = BasicArithmeticOps (Int) in
A.(8 + 3);;
- : int = 11
# let module A = BasicArithmeticOps (Int64) in
A.(4L + 3L);;
- : int64 = 7L
Related
This is the code I tried
fun printsl([], k) = true
| printsl(h::t) = if k > h then print(h) andalso printsl(t);
But when I run the code, i get the following error
= stdIn:4.68-7.8 Error: syntax error: deleting SEMICOLON ID
stdIn:8.1 Error: syntax error found at EOF
The goal of the function is to print any number in the list that is less than the value k
A few things wrong here. Let's start with your function signature.
On the first line, your function takes 2 parameters, an empty list and whatever the type of k is (it is not important yet). Then on the second line, the function takes just one parameter, a non-empty list.
The two lines should match to look like:
fun printsl([], k) = ...
| printsl(h::t, k) = ...
Now let's think about the use of andalso. andalso is an operator which takes two booleans and returns a bool. It can be considered to have the signature bool * bool -> bool.
Your usage print(h) andalso printsl(t) does not match this signature.
The type of print is string -> unit, so the type of print(h) is unit (assuming h to be a string). As such, the usage of andalso is incorrect as the types on each side are not bools.
Instead of using andalso, we can simply execute both statements (print(h); printsl(t, k)). Sequences like this are expressions which return the last value. That is to say (x; y; z) returns z.
fun printsl([], k) = true
| printsl(h::t, k) = if h < k then (print(h); printsl(t, k));
However, this is still broken as the if-else construct in SML is an expression and must have a matching else, so you could use either of the following:
fun printsl([], k) = true
| printsl(h::t, k) =
if h < k then (print(h); printsl(t))
else printsl(t, k);
fun printsl([], k) = true
| printsl(h::t, k) = (
if h < k then print(h) else ();
printsl(t, k)
);
I personally prefer the latter as it prevents repetition of printsl.
This code will compile, but the signature is wrong. As we use h directly as a parameter of print, its type is inferred to be a string. This means that the compiler determines printsl to have type string list * string -> bool, whereas we are aiming for int list * int -> bool.
This can be corrected by changing the call print(h) to print(Int.toString h), giving us:
fun printsl([], k) = true
| printsl(h::t, k) = (
if h < k then print(Int.toString h) else ();
printsl(t, k)
);
This is now a function which will print all values in the given list which are less than k, but it always returns true. This provides no extra information so I would be inclined to change the signature to int list * int -> unit, giving us (finally):
fun printsl([], k) = ()
| printsl(h::t, k) = (
if h < k then print(Int.toString h) else ();
printsl(t, k)
);
This entire program could also be written in a more functional manner using List.app and List.filter.
fun printsl (xs, k) =
List.app
(fn y => print (Int.toString y))
(List.filter
(fn x => x < k)
xs);
I am absolute OCaml beginner. I want to create a function that repeats characters 20 times.
This is the function, but it does not work because of an error.
let string20 s =
let n = 20 in
s ^ string20 s (n - 1);;
string20 "u";;
I want to run like this
# string20 "u"
- : string = "uuuuuuuuuuuuuuuuuuuu"
Your function string20 takes one parameter but you are calling it recursively with 2 parameters.
The basic ideas are in there, but not quite in the right form. One way to proceed is to separate out the 2-parameter function as a separate "helper" function. As #PierreG points out, you'll need to delcare the helper function as a recursive function.
let rec string n s =
if n = 0 then "" else s ^ string (n - 1) s
let string20 = string 20
It is a common pattern to separate a function into a "fixed" part and inductive part. In this case, a nested helper function is needed to do the real recursive work in a new scope while we want to fix an input string s as a constant so we can use to append to s2. s2 is an accumulator that build up the train of strings over time while c is an inductor counting down to 1 toward the base case.
let repeat s n =
let rec helper s1 n1 =
if n1 = 0 then s1 else helper (s1 ^ s) (n1 - 1)
in helper "" n
A non-tail call versions is more straightforward since you won't need a helper function at all:
let rec repeat s n =
if n = 0 then "" else s ^ repeat s (n - 1)
On the side note, one very fun thing about a functional language with first-class functions like Ocaml is currying (or partial application). In this case you can create a function named repeat that takes two arguments n of type int and s of type string as above and partially apply it to either n or s like this:
# (* top-level *)
# let repeat_foo = repeat "foo";;
# repeat_foo 5;;
- : bytes = "foofoofoofoofoo" (* top-level output *)
if the n argument was labeled as below:
let rec repeat ?(n = 0) s =
if n = 0 then "" else s ^ repeat s (n - 1)
The order of application can be exploited, making the function more flexible:
# (* top-level *)
# let repeat_10 = repeat ~n:10;;
# repeat_10 "foo";;
- : bytes = "foofoofoofoofoofoofoofoofoofoo" (* top-level output *)
See my post Currying Exercise in JavaScript (though it is in JavaScript but pretty simple to follow) and this lambda calculus primer.
Recursive functions in Ocaml are defined with let rec
As pointed out in the comments you've defined your function to take one parameter but you're trying to recursively call with two.
You probably want something like this:
let rec stringn s n =
match n with
1 -> s
| _ -> s ^ stringn s (n - 1)
;;
I just begin OCaml (and functional programming) today and I'm trying to code a function that count the number of occurrences of "value" into an array (tab).
I tried :
let rec count_occ tab value =
let rec count_rec idx time = function
| tab.length - 1 -> time
| _ when tab.(indice) == value-> count_rec (idx + 1) (time + 1)
| _ -> count_rec (indice + 1) time
in
count_rec 0 0
;;
Unfortunately, it doesn't compile because of a syntax error, and I don't find the solution.
let rec count_occ tab value =
This rec above is not necessary.
let rec count_rec idx time = function
| tab.length - 1 -> time
You cannot match against an expression. You want to use guards like you did on the next line, or if statements to test something like this. tab.length also does not exist as tab is an array, not a record with a length field. You want Array.length tab.
Really though, you don't want the function at all. function is the same as fun x -> match x with, and would imply that count_rec has type, int -> int -> int -> int.
| _ when tab.(indice) == value-> count_rec (idx + 1) (time + 1)
indices is not declared; lets assume you meant idx. Also, == is physical equality, you really want =.
| _ -> count_rec (indice + 1) time
in
count_rec 0 0
You're off to a good start, the basics of your recursion are correct although one edge case is incorrect, but a minor issue you should be able to resolve once you have the syntactic issues fixed.
finnaly I post my final code :
let count_occ tab value =
let rec count_rec idx time =
if (Array.length tab) = idx then
time
else if (tab.(idx)) = value then
count_rec (idx + 1) (time + 1)
else
count_rec (idx + 1) time
in
count_rec 0 0
;;
I am currently doing reasonably well in functional programming using F#. I tend, however, to do a lot of programming using recursion, when it seems that there are better idioms in the F#/functional programming community. So in the spirit of learning, is there a better/more idiomatic way of writing the function below without recursion?
let rec convert line =
if line.[0..1] = " " then
match convert line.[2..] with
| (i, subline) -> (i+1, subline)
else
(0, line)
with results such as:
> convert "asdf";;
val it : int * string = (0, "asdf")
> convert " asdf";;
val it : int * string = (1, "asdf")
> convert " asdf";;
val it : int * string = (3, "asdf")
Recursion is the basic mechanism for writing loops in functional languages, so if you need to iterate over characters (as you do in your sample), then recursion is what you need.
If you want to improve your code, then you should probably avoid using line.[2..] because that is going to be inefficient (strings are not designed for this kind of processing). It is better to convert the string to a list and then process it:
let convert (line:string) =
let rec loop acc line =
match line with
| ' '::' '::rest -> loop (acc + 1) rest
| _ -> (acc, line)
loop 0 (List.ofSeq line)
You can use various functions from the standard library to implement this in a more shorter way, but they are usually recursive too (you just do not see the recursion!), so I think using functions like Seq.unfold and Seq.fold is still recursive (and it looks way more complex than your code).
A more concise approach using standard libraries is to use the TrimLeft method (see comments), or using standard F# library functions, do something like this:
let convert (line:string) =
// Count the number of spaces at the beginning
let spaces = line |> Seq.takeWhile (fun c -> c = ' ') |> Seq.length
// Divide by two - we want to count & skip two-spaces only
let count = spaces / 2
// Get substring starting after all removed two-spaces
count, line.[(count * 2) ..]
EDIT Regarding the performance of string vs. list processing, the problem is that slicing allocates a new string (because that is how strings are represented on the .NET platform), while slicing a list just changes a reference. Here is a simple test:
let rec countList n s =
match s with
| x::xs -> countList (n + 1) xs
| _ -> n
let rec countString n (s:string) =
if s.Length = 0 then n
else countString (n + 1) (s.[1 ..])
let l = [ for i in 1 .. 10000 -> 'x' ]
let s = new System.String('x', 10000)
#time
for i in 0 .. 100 do countList 0 l |> ignore // 0.002 sec (on my machine)
for i in 0 .. 100 do countString 0 s |> ignore // 5.720 sec (on my machine)
Because you traverse the string in a non-uniform way, a recursive solution is much more suitable in this example. I would rewrite your tail-recursive solution for readability as follows:
let convert (line: string) =
let rec loop i line =
match line.[0..1] with
| " " -> loop (i+1) line.[2..]
| _ -> i, line
loop 0 line
Since you asked, here is a (bizarre) non-recursive solution :).
let convert (line: string) =
(0, line) |> Seq.unfold (fun (i, line) ->
let subline = line.[2..]
match line.[0..1] with
| " " -> Some((i+1, subline), (i+1, subline))
| _ -> None)
|> Seq.fold (fun _ x -> x) (0, line)
Using tail recursion, it can be written as
let rec convert_ acc line =
if line.[0..1] <> " " then
(acc, line)
else
convert_ (acc + 1) line.[2..]
let convert = convert_ 0
still looking for a non-recursive answer, though.
Here's a faster way to write your function -- it checks the characters explicitly instead of using string slicing (which, as Tomas said, is slow); it's also tail-recursive. Finally, it uses a StringBuilder to create the "filtered" string, which will provide better performance once your input string reaches a decent length (though it'd be a bit slower for very small strings due to the overhead of creating the StringBuilder).
let convert' str =
let strLen = String.length str
let sb = System.Text.StringBuilder strLen
let rec convertRec (count, idx) =
match strLen - idx with
| 0 ->
count, sb.ToString ()
| 1 ->
// Append the last character in the string to the StringBuilder.
sb.Append str.[idx] |> ignore
convertRec (count, idx + 1)
| _ ->
if str.[idx] = ' ' && str.[idx + 1] = ' ' then
convertRec (count + 1, idx + 2)
else
sb.Append str.[idx] |> ignore
convertRec (count, idx + 1)
// Call the internal, recursive implementation.
convertRec (0, 0)
In C/C++ you can implement a direct threaded interpreter with an array of function pointers. The array represents your program - an array of operations. Each of the operation functions must end in a call to the next function in the array, something like:
void op_plus(size_t pc, uint8_t* data) {
*data += 1;
BytecodeArray[pc+1](pc+1, data); //call the next operation in the array
}
The BytecodeArray is an array of function pointers. If we had an array of these op_plus operations then length of the array would determine how ofter we'd be incrementing the contents of data. (of course, you'd need to add some sort of terminating operation as the last operation in the array).
How would one go about implementing something like this in OCaml? I may be trying to translate this code too literally: I was using an OCaml Array of functions as in the C++. The problem with that is that I keep ending up with something like:
let op_plus pc data = Printf.printf "pc: %d, data_i: %d \n" pc data;
let f = (op_array.(pc+1)) in
f (pc+1) (data+1) ;;
Where op_array is an Array defined in the scope above and then redefine it later to be filled with a bunch of op_plus functions... however, the op_plus function uses the previous definition of op_array. It's a chicken&egg problem.
Another alternative would be using CPS and avoid explicit function array altogether. Tail call optimization still applies in this case.
I don't know how do you generate the code, but let's make not unreasonable assumption that at some point you have an array of VM instructions you want to prepare for execution. Every instruction is still represented as a function, but instead of program counter it receives continuation function.
Here is the simplest example:
type opcode = Add of int | Sub of int
let make_instr opcode cont =
match opcode with
| Add x -> fun data -> Printf.printf "add %d %d\n" data x; cont (data + x)
| Sub x -> fun data -> Printf.printf "sub %d %d\n" data x; cont (data - x)
let compile opcodes =
Array.fold_right make_instr opcodes (fun x -> x)
Usage (look at inferred types):
# #use "cpsvm.ml";;
type opcode = Add of int | Sub of int
val make_instr : opcode -> (int -> 'a) -> int -> 'a = <fun>
val compile : opcode array -> int -> int = <fun>
# let code = [| Add 13; Add 42; Sub 7 |];;
val code : opcode array = [|Add 13; Add 42; Sub 7|]
# let fn = compile code;;
val fn : int -> int = <fun>
# fn 0;;
add 0 13
add 13 42
sub 55 7
- : int = 48
UPDATE:
It's easy to introduce [conditional] branching in this model. if continuation is constructed from two arguments: iftrue-continuation and iffalse-continuation, but has the same type as every other continuation function. The problem is that we don't know what constitutes these continuations in case of backward branching (backward, because we compile from tail to head). That's easy to overcome with destructive updates (though maybe more elegant solution is possible if you are compiling from a high level language): just leave "holes" and fill them later when branch target is reached by the compiler.
Sample implementation (I've made use of string labels instead of integer instruction pointers, but this hardly matters):
type label = string
type opcode =
Add of int | Sub of int
| Label of label | Jmp of label | Phi of (int -> bool) * label * label
let make_instr labels opcode cont =
match opcode with
| Add x -> fun data -> Printf.printf "add %d %d\n" data x; cont (data + x)
| Sub x -> fun data -> Printf.printf "sub %d %d\n" data x; cont (data - x)
| Label label -> (Hashtbl.find labels label) := cont; cont
| Jmp label ->
let target = Hashtbl.find labels label in
(fun data -> Printf.printf "jmp %s\n" label; !target data)
| Phi (cond, tlabel, flabel) ->
let tcont = Hashtbl.find labels tlabel
and fcont = Hashtbl.find labels flabel in
(fun data ->
let b = cond data in
Printf.printf "branch on %d to %s\n"
data (if b then tlabel else flabel);
(if b then !tcont else !fcont) data)
let compile opcodes =
let id = fun x -> x in
let labels = Hashtbl.create 17 in
Array.iter (function
| Label label -> Hashtbl.add labels label (ref id)
| _ -> ())
opcodes;
Array.fold_right (make_instr labels) opcodes id
I've used two passes for clarity but it's easy to see that it can be done in one pass.
Here is a simple loop that can be compiled and executed by the code above:
let code = [|
Label "entry";
Phi (((<) 0), "body", "exit");
Label "body";
Sub 1;
Jmp "entry";
Label "exit" |]
Execution trace:
# let fn = compile code;;
val fn : int -> int = <fun>
# fn 3;;
branch on 3 to body
sub 3 1
jmp entry
branch on 2 to body
sub 2 1
jmp entry
branch on 1 to body
sub 1 1
jmp entry
branch on 0 to exit
- : int = 0
UPDATE 2:
Performance-wise, CPS representation is likely to be faster than array-based, because there is no indirection in case of linear execution. Continuation function is stored directly in the instruction closure. In the array-based implementation it has to increment program counter and perform array access (with an extra bounds checking overhead) first.
I've made some benchmarks to demonstrate it. Here is an implementation of array-based interpreter:
type opcode =
Add of int | Sub of int
| Jmp of int | Phi of (int -> bool) * int * int
| Ret
let compile opcodes =
let instr_array = Array.make (Array.length opcodes) (fun _ data -> data)
in Array.iteri (fun i opcode ->
instr_array.(i) <- match opcode with
| Add x -> (fun pc data ->
let cont = instr_array.(pc + 1) in cont (pc + 1) (data + x))
| Sub x -> (fun pc data ->
let cont = instr_array.(pc + 1) in cont (pc + 1) (data - x))
| Jmp pc -> (fun _ data ->
let cont = instr_array.(pc) in cont (pc + 1) data)
| Phi (cond, tbranch, fbranch) ->
(fun _ data ->
let pc = (if cond data then tbranch else fbranch) in
let cont = instr_array.(pc) in
cont pc data)
| Ret -> fun _ data -> data)
opcodes;
instr_array
let code = [|
Phi (((<) 0), 1, 3);
Sub 1;
Jmp 0;
Ret
|]
let () =
let fn = compile code in
let result = fn.(0) 0 500_000_000 in
Printf.printf "%d\n" result
Let's see how it compares to the CPS-based interpreter above (with all debug tracing stripped, of course). I used OCaml 3.12.0 native compiler on Linux/amd64. Each program was run 5 times.
array: mean = 13.7 s, stddev = 0.24
CPS: mean = 11.4 s, stddev = 0.20
So even in tight loop CPS performs considerably better than array. If we unroll loop and replace one sub instruction with five, figures change:
array: mean = 5.28 s, stddev = 0.065
CPS: mean = 4.14 s, stddev = 0.309
It's interesting that both implementations actually beat OCaml bytecode interpreter. The following loop takes 17 seconds to execute on my machine:
for i = 500_000_000 downto 0 do () done
You should not redefine op_array, you should fill it in with instructions by modifying it in place so that it's the same op_array that your functions already refer to. Unfortunately, you can't change the size of an array dynamically in OCaml.
I see two solutions:
1) if you don't need to change the sequence of "instructions", define them in a mutual recursion with the array op_array. OCaml allows mutually recursive functions and values that start with the application of a constructor to be defined. Something like:
let rec op_plus pc data = ...
and op_array = [| ... |]
2) Or use an additional indirection: make op_array a reference to an array of instructions, and refer in the functions to (!op_array).(pc+1). Later, after you have defined all the instructions, you can make op_array point to an array of the right size, full of the instructions you intend.
let op_array = ref [| |] ;;
let op_plus pc data = ... ;;
op_array := [| ... |] ;;
One more option (if the size is known beforehand) - initially fill the array with void instructions :
let op_array = Array.create size (fun _ _ -> assert false)
let op_plus = ...
let () = op_array.(0) <- op_plus; ...