Переопределить IO для упрощения отладки?

Я проходил слайды в http://www.algorithm.com.au/downloads/talks/monads-are-not-scary/monads-are-not-scary-chak.pdf

и прибл. 75% пути через колоду есть точка маркера "Переопределить IO для упрощения отладки!"

Это выглядит очень интригующей идеей! Может ли кто-нибудь дать практический пример того, о чем говорит оратор?

Ответ 1

Ну, что, если вместо IO вы использовали монаду, которая имитирует ввод-вывод с прекрасно контролируемой и оговоренной средой? Вы можете легко протестировать эти действия "IO", так как они были чистыми функциями. Это идея, например, IOSpec, которая идет еще дальше, позволяя вам точно указать, какой эффект вы хотите разрешить в своем имитированный IO, вы можете написать:

myFunction :: a -> b -> IOSpec (Teletype :+: IORefS)
myFunction x y = do
  ...
  putStr (...)
  ref <- newIORef ...
  ...

(телетайп разрешает терминальные функции, IORefS для ссылок) А затем проверьте свою функцию в свойстве quickcheck (см. Модуль VM и runIOSpec) с полным контролем ввода и вывода или даже поэтапно в GHCI. И если он работает правильно, просто измените импорт, чтобы ввести Test.IOSpec.Surrogate, который переопределяет IOSpec f как синоним для IO.