I'm trying to learn a bit more about F#'s computation expressions by implementing one of my own. However, I've hit a stumbling block with relation to the `Bind`

method. Here's what I've got so far:

```
type public op<'a> = Op of ('a list -> 'a list)
let inline (>>) (Op a) (Op b) = Op (a >> b)
module Op =
let id = Op id
let bind (b : 'b -> op<'a>) (v : 'b) = b v
let call (Op f) = f
let push v = Op (fun t -> v :: t)
// .. snip ..
type OpBuilder() =
member __.Bind (v, b) = Op.bind b v
member __.Yield (()) = Op.id
member __.Return (m) = Op.call m
[<CustomOperation("push")>]
member __.Push (m : op<'a>, v : 'a) = m >> Op.push v
// .. snip ..
let op = new OpBuilder()
```

Now, my understanding is that all of the following should be roughly equivalent:

```
// Use only the Op module methods
let f1 = Op.call(Op.bind (fun x -> Op.push x) 1)
// Use op builder with external closure
let f2 = Op.call(let x = 2 in op { push x })
// Use op builder bind explicitly
let f3 = op.Return(op.Bind(3, fun x -> op.Push(op.Yield(), x)))
// Use op builder with let! binding
let f4 = op { let! x = 4 in push x }
```

The first 3 seem to work fine, however, `f4`

gives this error:

This expression was expected to have type

unit

but here has type

int

I get the same error if I use `let`

instead of `let!`

. Everything I've read suggests that this is correct way to implement `Bind`

, but apparently I'm missing something. Can anyone point out what I'm doing wrong?

`op { push 2; dup; add } []`

→`[4]`

.`bind`

is not a bind, but just function application. To make it a monadic bind, the second parameter should be`op<'b>`

, not`'b`

.`let swap = op { let! x = pop; let! y = pop; push x; push y }`

and I figured starting with constant values (`let! x = 4`

) would be easier.`pop`

is a kind of`op<'a>`

since it modifies the "stack" but I had no clue how to retrieve the popped value as a variable.`pop`

- as its type would correspond to`'a list -> 'a * 'a list`

, the lone`'a`

being the popped value. I can give you an answer along these lines, but I wouldn't want to spoil the fun for you.8more comments