Рассмотрим фрагмент -
getLine >>= \_ -> getLine >>= putStr
Он делает разумную вещь, дважды запрашивая строку, а затем распечатывая последний ввод. Поскольку компилятор не имеет возможности узнать, какие внешние эффекты имеют getLine
, он должен выполнить их оба, даже если мы отбрасываем результат первого.
Мне нужно обернуть Монаду ввода-вывода в другую монаду (M), которая позволяет вычислениям ввода-вывода быть эффективными NOP, если не используются их возвращаемые значения. Таким образом, приведенная выше программа может быть переписана как что-то вроде -
runM $ lift getLine >>= \_ -> lift getLine >>= lift putStr
Где
runM :: M a -> IO a
lift :: IO a -> M a
И пользователь запрашивает ввод только один раз.
Однако я не могу понять, как написать эту монаду для достижения желаемого эффекта. Я не уверен, что это вообще возможно. Не мог бы кто-нибудь помочь?