I wrote these function to build a sequence from a function i am having a stack overflow error while testing it
let rec from_fun f ()=
match f () with
| None -> Nil
| Some e -> Cons(e, from_fun f)
from_fun (fun () -> let x = 0 in if x<10 then Some (x+1) else None)
thanks
Your function always returns Some 1. It never returns None. So the sequence is infinitely long and the stack overflows while building it.
If you want a function to return different values when you call it, you can do two things. First, you can pass it different parameters. This isn't possible for your design of from_fun--the parameter to the function is always (). Second, your function can be impure. I.e., the function can maintain some mutable state.
Here is an example of a generator:
let range_generator from below step =
let counter = ref from
in fun () ->
if (!counter < below)
then (let result = (Some !counter) in
counter := !counter + step;
result)
else None
For example, a call to range_generator 0 10 2 returns a closure over an internal counter mutable variable which generates all natural even numbers below 10:
# let gen = range_generator 0 10 2;;
val gen : unit -> int option = <fun>
Each call to gen possibly mutates the internal counter:
# gen();;
- : int option = Some 0
# gen();;
- : int option = Some 2
# gen();;
- : int option = Some 4
# gen();;
- : int option = Some 6
# gen();;
- : int option = Some 8
# gen();;
- : int option = None
# gen();;
- : int option = None
With your function:
# from_fun (range_generator 0 5 1);;
- : int list = [0; 1; 2; 3; 4]
The variable x you are using is local to the anonymous function you are using. As a result the function always return Some 1.
What you probably wanted to do is for the function to take an argument:
let rec from_fun f n =
match f n with
| None -> Nil
| Some e -> Cons(e, from_fun f e)
let seq = from_fun (fun x -> if x<10 then Some (x+1) else None) 0
EDIT:
Here is a solution with the appropriate type signature:
let rec from_fun f () =
match f () with
| None -> Nil
| Some e -> Cons(e, from_fun f ())
let x = ref 0
let seq = from_fun
(fun () ->
let v = !x in
if v < 10
then begin
x := v + 1;
Some v
end
else None)
()
It is worth noting that because of the side effects, you would have to reinitialise x before building a new sequence. The unit argument passed in parameter to from_fun is unnecessary, you could remove it.
Related
When declaring a function, I've 3 different ways:
let f x = ...
let f = (fun x -> ...)
let f = function
| ... -> (pattern matching)
It's this last one that I don't fully understand how it works.
I was doing a function that, considering a list (we'll assume it has integers in it but could be anything), reverses it, pretty basic, but with a complexity of O(n). After struggling for an hour at least I check the answer, and it is written like this:
let reverse lst =
let rec aux acc = function
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
I thought that using the key word function was just another way of doing patter matching, but when I do this:
let reverse lst =
let rec aux acc =
match aux with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst
It doesn't work, and idk why. On top of that, why can we add tl at the end of the first function? Isn't aux a single argument function?
There are a few problems with this question. First, the code you give as the solution for reverse is not valid OCaml. It matches aux (which is a function) against list patterns. Most likely aux was supposed to be acc. But even so it doesn't seem right because it should have two arguments (the accumulated result and the input that still needs to be processed).
Second, your two code examples are the same. You seem to be saying that one works and one doesn't work. That doesn't make sense since they're the same.
IMHO you need to rewrite the question if you want to get a helpful answer.
Ocaml uses currying, which means that a two-argument function is the same thing that a function whose return value is a function.
To define a two-argument function, you can combine all the ways you know of creating one-argument functions:
let f x y = x + y
let f x = (fun y -> x + y)
let f x = function
| y -> x + y
let f = (fun x -> (fun y -> x + y))
let f = function
| x -> function
| y -> x + y
let f x = (let g y = x + y in g)
etc, etc.
All these definitions for f lead to the same result:
val f : int -> int -> int = <fun>
# f 3 4;;
- : int = 7
Note that the signature of f is:
val f : int -> int -> int = <fun>
If we added parentheses to better understand this signature, it would be this:
val f : int -> (int -> int) = <fun>
Meaning that f is a one-argument function whose return value is a one-argument function whose return value is an int.
Indeed, if we partially apply f:
# f 3;;
- : int -> int = <fun>
# let add_three = f 3;;
val add_three : int -> int = <fun>
# add_three 4;;
- : int = 7
The code you give at the end of your question is wrong. It's most likely intended to be this:
let reverse lst =
let rec aux acc l =
match l with
| [] -> acc
| hd :: tl -> aux (hd :: acc) tl
in
aux [] lst;;
val reverse : 'a list -> 'a list = <fun>
# reverse [1;2;3;4;5];;
- : int list = [5; 4; 3; 2; 1]
The function aux only has one param n. Why can it accept list at the bottom?
# let length list =
let rec aux n = function
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 list;;
val length : 'a list -> int = <fun>
The function expression produces a function of one argument.
# function [] -> 0 | _ -> 1;;
- : 'a list -> int = <fun>
Now, if you write a function f that takes a parameter n, and whose body contains function, as follows:
# let f n = function [] -> 0 | _ -> n;;
val f : int -> 'a list -> int = <fun>
Then f is a function that takes n and returns a function of a single argument.
# f 3;;
- : '_weak1 list -> int = <fun>
The returned value is a function that takes a list of some unknown type of values, and returns an integer (the _weak prefix is related to Weak Type Variables, this is not important here).
Since the returned value is a function, you can apply it:
# (f 3) ["test"];;
- : int = 3
You can drop the parentheses around f 3 because that's how function application is grouped by default:
# f 3 ["test"];;
- : int = 3
So what looks like a function taking two arguments is in fact a function taking one argument, evaluating to a function to which we apply the second argument.
(See also Currying)
The function keyword introduces a function which takes a single argument, which it pattern matches.
This is equivalent to:
let length lst =
let rec aux n lst =
match lst with
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 lst
Or...
let length lst =
let rec aux n =
fun lst ->
match lst with
| [] -> n
| _ :: t -> aux (n + 1) t
in
aux 0 lst
function keyword will match the last argument, even it’s not declared in the left side of =.
Compare with match .. with, the match needs the argument name show up.
Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
I have a problem on my program, when I call on the Ocaml terminal "#matrix81 cache;;" it gives me the error: "This expression has type cache list but is here used with type cache list"
This is my code. Any help?
let rec makeLine w =
let y = w - 1 in
if w <> 0 then 0::(makeLine y)
else []
;;
let rec makeMatrix w h =
let y = h - 1 in
if h <> 0 then (makeLine w)::(makeMatrix w y)
else []
;;
let rec checkCache lc d t =
match lc with
[] -> 0
|x::xs -> if (x.difficulty = d) && (x.terrain = t) then (checkCache xs d t) + 1
else (checkCache xs d t)
;;
let rec checkLine lc d t line =
match line with
[]->[]
|x::xs -> let nt = t +. 0.5 in
let v = 5.0 in
if (nt < v) then
let nx = (checkCache lc d t) in
(nx)::(checkLine lc d nt xs)
else []
;;
let rec matrix81Aux m d lc =
match m with
[] -> []
|x::xs -> let nd = d +. 0.5 in
let v = 5.0 in
if (nd < v) then
(checkLine lc d 1.0 x)::(matrix81Aux xs nd lc)
else []
;;
let matrix81 lc =
let m = makeMatrix 9 9 in
matrix81Aux m 1.0 lc
;;
You don't show the definition of the type cache (or give the line number for the error).
The most common cause of this strange type of error message is that you have defined the same type name twice. This often happens when working from the toplevel and loading files with #use.
It's also possible you're defining the name cache twice some other way.
Recent versions of OCaml add an integer to the type name, to (try to) clarify that two different types are involved:
# type cache = A | B;;
type cache = A | B
# let f = function A -> 3 | B -> 4;;
val f : cache -> int = <fun>
# type cache = C | D;;
type cache = C | D
# let g x = match x with C -> f x | D -> 14;;
Error: This expression has type cache/1023
but an expression was expected of type cache/1018
Can someone explain the syntax used for when you have nested functions?
For example I have a outer and an inner recursive function.
let rec func1 list = match list with
[] -> []
|(head::tail) ->
let rec func2 list2 = match list2 with
...
;;
I have spent all day trying to figure this out and I'm getting a ever tiring "Syntax error".
You don't show enough code for the error to be obvious.
Here is a working example:
# let f x =
let g y = y * 5 in
g (x + 1);;
val f : int -> int = <fun>
# f 14;;
- : int = 75
Update
Something that might help until you're used to OCaml syntax is to use lots of extra parentheses:
let rec f y x =
match x with
| h :: t -> (
let incr v = if h = y then 1 + v else v in
incr (f y t)
)
| _ -> (
0
)
It's particularly hard to nest one match inside another without doing this sort of thing. This may be your actual problem rather than nested functions.
I tried to use memoization technique to optimize the caculation of Fibonacci. My code is:
let memo f =
let vtable = ref [] in
let rec match_function x vt=
match vt with
|(x',y)::_ when x=x' -> y
|_::l ->
match_function x l
|[] ->
let y = (f x) in
vtable := (x,y):: !vtable;
y
in
(fun x -> (match_function x !vtable));;
let rec ggfib = function
0|1 as i -> i
|x -> ggfib(x-1) + ggfib(x-2);;
let memoggfib = memo ggfib;;
let running_time f x =
let start_time = Sys.time () in
let y = f x in
let finish_time = Sys.time() in
Printf.printf "Time lapse:%f\n" (finish_time -. start_time);
y;;
running_time ggfib 30;;
running_time memoggfib 30;;
The output is:
Time lapse:0.357187
Time lapse:0.353663
The difference is not that much.. Why?? And even worse, when I tried to calculate Fibonacci at 40 using
running_time ggfib 40;;
running_time memoggfib 40;;
The program appears to run into a infinite loop and stop outputting.
What is wrong here? What problem I did not take care of?
I changed the code above, to introduce a 'static' vtable for memoization.
let rec ggfib = function
0|1 as i -> i
|x -> ggfib(x-1) + ggfib(x-2);;
let running_time x0 =
let vtable = ref [] in
let start_time = Sys.time () in
let x = ref 1 in
let rec match_function ff x vt=
match vt with
|(x',y)::_ when x=x' -> y
|_::l ->
match_function ff x l
|[] ->
let y = (ff x) in
vtable := (x,y):: !vtable;
y
in
let y=ref 1 in
while !x<x0 do
y:= match_function ggfib !x !vtable;
x:=!x+1;
done;
let finish_time = Sys.time() in
Printf.printf "Time lapse:%f\n" (finish_time -. start_time);
y;;
let running_time2 x0=
let start_time = Sys.time () in
let x = ref 1 in
while !x<x0 do
ggfib !x;
x:=!x+1;
done;
let finish_time = Sys.time() in
Printf.printf "Time lapse:%f\n" (finish_time -. start_time);;
running_time 40;;
running_time2 30;;
It still acts as the basically same. I didn't see a significant improvement....
Time lapse:0.581918
Time lapse:0.577813
It looks to me like you're just memoizing the outermost calls. The inner calls are to ggfib, not to (memo ggfib).
When you call memoggfib, the memo function will remember the value of the outermost call. However, the inner calls are handled by ggfib (the function that you passed to memo). If you look at the definition of ggfib, you see that it calls itself. It doesn't call (memo ggfib).
I don't see a way to turn an ordinary (recursive) function into a memoized one. It won't automatically call the memoized version of itself internally.
If you start with a function that's intended to be memoized, I still see problems "tying the knot".
(* a "derecursified" version of fibonacci: recursive calls are
replaced by calls to a function passed as parameter *)
let rec fib_derec f = function
| 0|1 as i -> i
| n -> f (n - 1) + f (n - 2)
(* to get the fibonacci back we need to compute a fixpoint:
fib_derec should get passed 'fib' as parameter,
which we will define in term of fib_derec
*)
let rec fib n = fib_derec fib n
let test = Array.init 10 fib
(* [|0; 1; 1; 2; 3; 5; 8; 13; 21; 34|] *)
(* we can make this construction generic *)
let rec fix derec input = derec (fix derec) input
let fib = fix fib_derec
let test = Array.init 10 fib
(* [|0; 1; 1; 2; 3; 5; 8; 13; 21; 34|] *)
(* Trick: we can use this tying-the-knot operator to insert
memoization "between the recursive calls" of the recursive function *)
let rec memo_fix table derec =
fun input ->
try Hashtbl.find table input with Not_found ->
let result = derec (memo_fix table derec) input in
Hashtbl.add table input result;
result
let fib_table = Hashtbl.create 100
let fib = memo_fix fib_table fib_derec
let test = Array.init 10 fib
(* [|0; 1; 1; 2; 3; 5; 8; 13; 21; 34|] *)
let test2 = fib 1000
(* -591372213: overflow, but quick result *)