Many of you offered a solution along the following lines: type 'a state = int -> 'a * int;; let unit (a : 'a) : 'a state = fun count -> (a, count);; let bind (u : 'a state) (f : 'a -> 'b state ) : 'b state = fun count -> let (a, count') = u count in f a count';; (* Looks good so far, now how are we going to increment the count? *) let lift2 (f : 'a -> 'b -> 'c) (u : 'a state) (v : 'b state) : 'c state = bind u (fun x -> bind v (fun y -> fun count -> (f x y, count + 1)));; Whoops. That will work for the cases you're probably thinking about. For instance, you can do: lift2 (+) (unit 1) (lift2 (+) (unit 2) (unit 3));; and you'll get back an `int state` that when applied to a starting count of `0` yields the result `(6, 2)`---that is, the result of the computation was 6 and the number of operations was 2. However, there are several problems here. First off, you shouldn't name your function `lift2`, because we're using that name for a function that's interdefinable with `bind` in a specific way. Our canonical `lift2` function is: let lift2 (f : 'a -> 'b -> 'c) (u : 'a state) (v : 'b state) : 'c state = bind u (fun x -> bind v (fun y -> unit (f x y)));; (Haskell calls this `liftM2`, and calls our `lift` either `liftM` or `mapM`.) OK, so then you might call your function `loft2` instead. So what? The remaining problem is more subtle. It's that your solution isn't very modular. You've crafted a tool `loft2` that fuses the operation of incrementing the count with the behavior of our `lift2`. What if we needed to deal with some unary functions as well? Then you'd need a `loft1`. What if we need to deal with some functions that are already monadic? Then you'd need a tool that fuses the count-incrementing with the behavior of `bind`. And so on. It's nicer to just create a little module that does the count-incrementing, and then use that together with the pre-existing apparatus of `bind` and (our canonical) `lift` and `lift2`. You could do that like this: let tick (a : 'a) : 'a state = fun count -> (a, count + 1);; let result1 = bind (lift2 (+) (unit 1) (bind (lift2 (+) (unit 2) (unit 3)) tick)) tick;; result1 0;; (* evaluates to (6, 2) *) Or like this: let tock : unit state = fun count -> ((), count + 1);; let result2 = bind tock (fun _ -> lift2 (+) (unit 1) (bind tock (fun _ -> lift2 (+) (unit 2) (unit 3))));; result2 0;; (* evaluates to (6, 2) *)