Applicative "identity" law states pure id <*> v == v, but Form violates it.
This is because its (<*>) instance adds incFormId between the two actions. As a result, pure id <*> v executes v with the incremented FormId.
I think (<*>) doesn't have to do incFormId. Instead, functions like Generalized.input should call incFormId just before they get input for themselves, because it is they who need to generate new FormIds. So, incFormId, getFormInput and getFormId might as well be atomic.
Applicative "identity" law states
pure id <*> v == v, butFormviolates it.This is because its
(<*>)instance addsincFormIdbetween the two actions. As a result,pure id <*> vexecutesvwith the incrementedFormId.I think
(<*>)doesn't have to doincFormId. Instead, functions likeGeneralized.inputshould callincFormIdjust before they get input for themselves, because it is they who need to generate newFormIds. So,incFormId,getFormInputandgetFormIdmight as well be atomic.