Подтвердить что ты не робот

Haskell - двойная личность IO/ST монада?

У меня есть код, который в настоящее время использует ST-монаду для оценки. Мне нравится не помещать IO повсюду, потому что метод runST создает чистый результат и указывает, что такой результат безопасен для вызова (по сравнению с unsafePerformIO). Однако, поскольку некоторые из моих кодов получили больше, я хочу, чтобы вывести отладочные заявления печати. ​​

Существует ли какой-либо класс, который предоставляет монаду с двумя личностью [или машиной для машинного оборудования], которая может быть ST или IO (в зависимости от ее типа или флага isDebug)? Я помню, SPJ представила класс "Мутация" в своей статье "Развлечения с типом функций", в которой использовались ассоциативные типы для привязки IO к IORef и ST к STRef. Существует ли такое как пакет где-то?

Редактировать/решить

Большое спасибо [nth time], C.A. McCann! Используя это решение, я смог ввести дополнительный класс для монад, поддерживающих функцию pdebug. Монада ST будет игнорировать эти вызовы, тогда как IO будет запускать putStrLn.

class DebugMonad m where
    pdebug :: String -> m ()

instance DebugMonad (ST s) where
    pdebug _ = return ()

instance DebugMonad IO where
    pdebug = putStrLn

test initV = do
    v <- newRef initV
    modifyRef v (+1)
    pdebug "debug"
    readRef v
testR v = runST $ test v

Это очень удачное последствие в ghci. Поскольку ожидается, что выражения будут типами ввода-вывода по умолчанию, запуск чего-то типа "тест 3" приведет к тому, что будет выполняться монада IO, чтобы вы могли легко отлаживать его, а затем называть его чем-то вроде "testR", когда вы действительно хотите запустить он.

4b9b3361

Ответ 1

Если вам нужен унифицированный интерфейс IORef и STRef, просмотрели ли вы пакет stateref? Он имеет классы типов для "ссылок на изменяемые данные", разделенных для чтения, записи и т.д. С экземплярами для IORef и STRef, а также такими вещами, как TVar, MVar, ForeignPtr и т.д..