Ну, а что если вместо ввода-вывода вы использовали монаду, которая имитирует ввод-вывод в идеально контролируемой и оговоренной среде?Вы можете легко проверить эти действия "IO", как будто они были чистыми функциями.Это идея, к примеру, IOSpec , которая идет еще дальше, позволяя вам точно указать, какой эффект вы хотите разрешить в своем имитируемом вводе-выводе, вы можете написать:
myFunction :: a -> b -> IOSpec (Teletype :+: IORefS)
myFunction x y = do
...
putStr (...)
ref <- newIORef ...
...
(телетайп разрешает функции терминала, IORefS - ссылки). Затем протестируйте свою функцию, например, в свойстве быстрой проверки (см. модуль VM и runIOSpec) с полным контролем над вводом и выводом или даже пошагово в GHCI.И если он работает правильно, просто измените импорт, чтобы ввести Test.IOSpec.Surrogate, который переопределяет IOSpec f в качестве синонима для IO.