Trying int streams

I try the following:

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
    ()

Feel free to comment.

First, you can’t define a type in that particular position. Second, this type, more or less, is the existing standard Seq.t :slightly_smiling_face:

2 Likes

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.

2 Likes

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).

Warning 26 [unused-var]: unused variable mytail.
6- : unit = ()
#