to post messages and comments.

ТУНЕЛЛИРУЮ ТУНЕЛЛИРУЮ
Правда, волшебный автовывод инстенсов так и не осилил. Пришлось остановиться на таком говне:

class (MonadIO o) => EmbedIO o where
type Content o
callback :: o a -> Content o -> IO a

— If the inner monad is IO

data Void

instance EmbedIO IO where
type Content IO = Void
callback action _ = action

и в приложении:

runNPT_ :: NPT a -> NPTState -> IO a
runNPT_ x s = do
runReaderT x s

instance EmbedIO NPT where
type Content NPT = NPTState
callback act cont = runNPT_ act cont

Модифицируемый стейт будет в IORef'ах. Уродливо, но лучше я не придумал; не переписывать же MState, чтобы был кишками наружу, дабы можно было инстенс написать.

Все-таки, полтора года некодинга ничего умного сказываются. Читаю спеку по DHT и страшно туплю над реализацией, а ведь просто префиксное дерево и пачка сообщений протокола.