Обычным соглашением является разделение вашего модуля на общедоступную и частную части, то есть
module SomeModule.Internal where
-- ... exports all private methods
, а затем открытый API
module SomeModule where (export1, export2)
import SomeModule.Internal
. Затем вы можете импортировать SomeModule.Internal
в тестах и в других местах, где важно получить доступ к внутренней реализации.
Идея состоит в том, что пользователи вашей библиотеки никогда случайно не вызывали частный API, но они может использовать его, если знать, что они делают (отладка и т. д.). Это значительно увеличивает удобство использования вашей библиотеки по сравнению с принудительным скрытием частного API.