I want to create a stream monad with the return
and bind
operations
I tried the following:
module type STREAM_MONAD_SIG =
sig
type 'a stream
val return : 'a -> 'a stream
val bind : 'a stream -> ('a -> 'b stream ) -> 'b stream
val (>>=) : 'a stream -> ('a -> 'b stream ) -> 'b stream
val div5 : 'a stream -> 'a stream
end
module StMonad : STREAM_MONAD_SIG = struct
type 'a stream = Nil | Cons of 'a * ( unit -> 'a stream)
let return v = Cons(v, fun() -> Nil)
let rec bind v f =
match v with
| Nil -> Nil
| Cons(h, t) ->
match f h with
| Nil -> bind (t()) f
| Cons(r_h, _) -> Cons(r_h, fun () -> bind (t()) f)
let (>>=) = bind
let div5 s1 = s1 >>= fun x -> if x mod 5 == 0 then return x else Nil
let add2 s1 = s1 >>= fun x -> return (x+2)
end
My question is: Can this bind function be used both as a map and filter operation based on the type of f
we pass? Filter application like div5
, and add2
for map.
Example Input for div5
:
open StMonad;;
let st = Cons(5, fun () -> Cons(6, fun () -> Cons(10, fun () -> Nil)));;
let res = div5 st;;
Output: Cons(5, Cons(10, fun () -> Nil))
.