let _ =
type stream = Nil | Cons of int * (unit -> stream)
let fib1 : stream =
let rec fibgen (a : int) (b : int) : stream =
Cons(a, fun () -> fibgen b (a + b)) in
fibgen 1 1 in
take fib1 20 in
()
Currently i try to sum a sequence, but code below fails
type 'a seq =
| Nil
| Cons of 'a * (unit -> 'a seq)
let _=
let myhead (Cons (x,_))=x in
let mytail (Cons (_,f))=f() in
let l1=Cons (1,fun() -> Nil) in
let l2=Cons (2,fun() -> l1) in
let l3=Cons (3,fun() -> l2) in
let rec mysum alist= match alist with
| Cons(hd,tl) -> hd+ mysum(tl())
| Nil -> 0 in
let s=mysum l3 in
print_int s in
()
The code does not print 6. s seems to be no integer.
Rewriting to a slightly more idiomatic style (and I really mean slightly, I wouldn’t write such code because myhead and mytail is not what seems good functional code) yields it working just fine:
type 'a seq =
| Nil
| Cons of 'a * (unit -> 'a seq)
let myhead = function
| Cons (x, _) -> x
| Nil -> raise @@ Failure "Incomplete function"
let mytail = function
| Cons (_, f) -> f ()
| Nil -> raise @@ Failure "Incomplete function"
let l1 = Cons (1, fun () -> Nil)
let l2 = Cons (2, fun () -> l1)
let l3 = Cons (3, fun () -> l2)
let rec mysum = function
| Cons (hd, tl) -> hd + (mysum @@ tl ())
| Nil -> 0
let () =
let s = mysum l3 in
print_int s
I’m learning so it’s in step by step base. The error i had made was that the match i used was not exhaustive. The idea is to improve it later with eg. fibonacci / lazyness / iterators / stream.
Program below compiles fine.
It’s based on info from " Better Programming Through OCaml from Michael R. Clarkson"
type 'a seq =
| Nil
| Cons of 'a * (unit -> 'a seq)
let _=
let myhead z =match z with
| Cons (x,_) -> x
| Nil -> 0 in
let mytail z=match z with
| Cons (_,f) -> f()
| Nil -> Nil in
let rec mysum z= match z with
| Cons (hd, tl) -> hd + (mysum (tl ()))
| Nil -> 0 in
let rec mytake n s =
if n = 0 then []
else (myhead s) :: (mytake (n - 1) (mytail s)) in
let rec myprintlist al= match al with
| [] -> ()
| hd::tl -> print_int hd;
myprintlist tl in
let rec natnumseq n = Cons (n, fun () -> natnumseq (n + 1)) in
let nats = natnumseq 0 in
let _= myprintlist (mytake 10 nats) in
let l1=Cons (1,fun() -> Nil) in
let l2=Cons (2,fun() -> l1) in
let l3=Cons (3,fun() -> l2) in
let _= myprintlist (mytake 3 l3) in
let _= print_int (mysum l3) in
()
Still i wonder how to define a sequence of explicit only ints.
Because the type declares a sequence of a random type 'a
I would still recommend you to learn with a more conventional style and unlearn habits from other languages. The way you’re currently writing seems very much like you’re trying to write a different language in OCaml which will lead you to constantly fight the language.
In this case myhead Nil gives 0 which I would say is not correct and is only valid if your 'a seq is an int seq. Feeding it something like myhead (Cons "a", (fun () -> Nil)) would not work, because it would have to return both an int and a string.
That’s easy:
type intseq = int seq
There you go, you have now substituted the 'a with int and named it intseq.
I inserted a “;;” after the type-definition, and then copy-pasted into a fresh ocaml toplevel. The last bit of output is below. Remember that print_int doesn’t print a newline after its output (so that it can be combined with other print_xx functions).