«Настоящий» ленивый ввод-вывод в Haskell

Рассмотрим фрагмент -

getLine >>= \_ -> getLine >>= putStr

Он делает разумную вещь, дважды запрашивая строку, а затем распечатывая последний ввод. Поскольку компилятор не имеет возможности узнать, какие внешние эффекты имеют getLine , он должен выполнить их оба, даже если мы отбрасываем результат первого.

Мне нужно обернуть Монаду ввода-вывода в другую монаду (M), которая позволяет вычислениям ввода-вывода быть эффективными NOP, если не используются их возвращаемые значения. Таким образом, приведенная выше программа может быть переписана как что-то вроде -

runM $ lift getLine >>= \_ -> lift getLine >>= lift putStr

Где

runM :: M a -> IO a
lift :: IO a -> M a

И пользователь запрашивает ввод только один раз.

Однако я не могу понять, как написать эту монаду для достижения желаемого эффекта. Я не уверен, что это вообще возможно. Не мог бы кто-нибудь помочь?

6
задан Anupam Jain 25 August 2011 в 13:36
поделиться