From: Warren Harris <warrensomebody@gmail.com>
To: caml-list@yquem.inria.fr
Subject: cost of monads
Date: Sat, 21 Jun 2008 11:23:54 -0700 [thread overview]
Message-ID: <3822B729-FD99-429E-8150-CEAA57E4D84F@gmail.com> (raw)
I'm considering writing a moderate sized program with high performance
needs in a monad / monad transformer style in ocaml. Although I
believe that this abstraction will offer me benefits in hiding some
complexity, some of the monad transformers I would like to "stack" are
quite simple (e.g. a state-transition monad), and I'm concerned that
my program will be paying a high performance cost due to high function
call overhead -- ones which cannot be optimized away due to module
boundaries.
I know that the real answer here is "profile it and find out"... but I
thought that asking for other's experience might be a good first step.
Perhaps someone can offer a technique to make this work well, or a
word of caution on why this should be avoided. I realize that most of
the monad work happens in haskell (and I sometimes feel that I'm
reinventing the wheel -- although it's very educational!), but I'd
prefer to stick with ocaml if possible.
Warren
(* -*- Mode: Caml; tab-width: 4; indent-tabs-mode: nil -*- *)
(******************************************************************************)
module type MONAD =
sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
end
module type ID_MONAD =
sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
val run : 'a t -> 'a
end
module IdM : ID_MONAD =
struct
type 'a t = 'a
let return a = a
let (>>=) m f = f m
let run a = a
end
(******************************************************************************)
module type STATE_MONAD =
sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
type s
type 'a m
val lift : 'a m -> 'a t
val run : 'a t -> s -> 'a m
val gets : s t
val puts : s -> unit t
end
module type STATE = sig type s end
module StateT(M:MONAD)(S:STATE) : STATE_MONAD with type s = S.s =
struct
type 'a m = 'a M.t
type s = S.s
type 'a t = s -> ('a * s) M.t
let return a s = M.return (a, s)
let (>>=) m f s = M.(>>=) (m s) (fun (a, s) -> f a s)
let lift m s = M.(>>=) m (fun a -> M.return (a,s))
let run m s = M.(>>=) (m s) (fun (a, _) -> M.return a)
let gets s = M.return (s, s)
let puts s _ = M.return ((), s)
end
(******************************************************************************)
module type KMONAD =
sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
type 'a m
type ans
val lift : 'a m -> 'a t
val run : ans t -> ans m
val callcc : (('a -> 'b t) -> 'a t) -> 'a t
end
module type K = sig type ans end
module KMonadT(M:MONAD)(K:K) : KMONAD with type ans = K.ans =
struct
type ans = K.ans
type 'a m = 'a M.t
type 'a t = ('a m -> ans m) -> ans m
let lift m k = k m
let return a k = k (M.return a)
let (>>=) m f k = m (fun am -> M.(>>=) am (fun a -> f a k))
let run m = m (fun a -> a)
let callcc f k = f (fun a _ -> return a k) k
end
(******************************************************************************)
next reply other threads:[~2008-06-21 18:23 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-21 18:23 Warren Harris [this message]
2008-06-21 23:41 ` [Caml-list] " David Teller
2008-06-22 2:32 ` Brian Hurt
2008-06-22 19:02 ` Warren Harris
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3822B729-FD99-429E-8150-CEAA57E4D84F@gmail.com \
--to=warrensomebody@gmail.com \
--cc=caml-list@yquem.inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox