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) *)
```