My understanding of the State Monad is that these two functions are very similar:

```
addIncState :: Number -> State Int Number
addIncState n = do
state <- get
modify_ (_ + 1)
pure $ toNumber state + n
addIncTuple :: Tuple Int Number -> Tuple Int Number
addIncTuple (Tuple state val) = Tuple (state + 1) (toNumber state + val)
```

The key difference is that the type signature is much more descriptive when `State`

is used.

I recently re-wrote an algorithm that was searching a pretty expansive state-space. I switched from manually threading state to using the State monad. It worked, but the final result was an algorithm that was considerably slower.

Is that a surprising result or is it an expected result?

Does this added level of abstraction come with a performance trade-off? I have read that Monad Transformers and Type Classes combine to create broadly applicable/well architected code at the cost of performance. I gather the problem there, however, isnât applicable to Monads as a whole.

A quick look at the compiled code:

```
var addIncTuple = function (v) {
return new Data_Tuple.Tuple(v.value0 + 1 | 0, Data_Int.toNumber(v.value0) + v.value1);
};
var addIncState = function (n) {
return Control_Bind.bind(Control_Monad_State_Trans.bindStateT(Data_Identity.monadIdentity))(Control_Monad_State_Class.get(Control_Monad_State_Trans.monadStateStateT(Data_Identity.monadIdentity)))(function (state) {
return Control_Bind.discard(Control_Bind.discardUnit)(Control_Monad_State_Trans.bindStateT(Data_Identity.monadIdentity))(Control_Monad_State_Class.modify_(Control_Monad_State_Trans.monadStateStateT(Data_Identity.monadIdentity))(function (v) {
return v + 1 | 0;
}))(function () {
return Control_Applicative.pure(Control_Monad_State_Trans.applicativeStateT(Data_Identity.monadIdentity))(Data_Int.toNumber(state) + n);
});
});
};
```

While `addIncTuple `

is much more straight forward. I donât really spot the gotcha with State, is it death by a thousand cuts or has it given me just enough rope to shoot myself in the foot?