Я пишу программу в Scala и стараюсь оставаться функционально чистым, насколько это возможно. Проблема, с которой я сталкиваюсь, не специфична для Scala; это больше связано с попыткой кода функционально. Логика функции, которую я должен кода идет что-то вроде:Как отделить проблемы функционально
- Потратьте некоторое значение типа А
- Используйте это значение для формирования информации из журнала
- Войти эту информацию посредством вызова функции во внешней библиотеке и оценивать статус возврата для действия регистрации (т. е. был ли он успешным журналом или произошел сбой регистрации)
- Независимо от того, был ли журнал успешным или неудачным, я должен вернуть значение ввода.
Причина для возвращения значения входного в качестве выходного значения, что эта функция будет состоять с другой функцией, которая требует значения типа А.
Учитывая выше, функцию Я пытаюсь кода действительно имеет тип A => A
, т. е. он принимает значение типа A
и возвращает значение типа A
, но между ними выполняется некоторая регистрация. Тот факт, что я возвращаю то же значение обратно, которое я ввел, заставляет эту функцию сводиться к функции идентификации!
Это похоже на запах кода для меня, и мне интересно, что я должен сделать, чтобы сделать эту функцию более чистой. Как я могу выделить здесь проблемы? Также тот факт, что функция журнала уходит и регистрирует информацию, означает, что я действительно должен обернуть этот вызов в монаду IO
и вызвать функцию unsafePerformIO
. Любые идеи приветствуются.
Если единственной целью является регистрация, это должно быть 'A -> IO()' not 'A -> A'. –
функция ведения журнала не обязательно имеет какое-либо отношение к IO, но вы можете использовать Writer Monad, возможно, оставив вам функцию типа A => Writer A', которая затем вы можете выполнить операции ввода-вывода на –
Я принял совет @BartekBanachewicz и изменил подпись функции на «A -> IO [Unit]». Затем я составляю другие функции с этим действием IO монадически в выражении for (эквивалент 'do' в Haskell). –