по моему небольшому опыту оно не стоит возьни.
У меня была похожая задача с выбором версии протокола и последующей проверкой этой версии. И в зависимости от версии протокола сообщения могут быть слегка разными. Сначала казалось, что оно очень красиво укладывается в GADT, но в итого выросло в мешанину из динамических проверок и типостраданий. Проще оказалось выделить чистую часть протокола в простенькую стейт-машину, грубо говоря,
respond :: Session -> Message -> (ResponseMessage, Session)