User
data SenderState = ReadyToSendHello | HasSentHello | HasSentNumber | HasReceivedNumber data Sender (a :: SenderState) = Sender SenderImpl sendHello :: Sender ReadyToSendHello -> Sender HasSentHello sendHello (Sender impl) = Sender $ send_message "HELLO" impl waitRespondToHelloYou :: Sender HasSentHello -> Sender HasSentNumber waitRespondToHelloYou (Sender impl) = Sender $ ...
PS. Ещё singletons есть, но для этого случая они таки думаю overkill.