Выход из монады ввода-вывода внутри монады продолжения

Непонятное название для сбивающего с толку вопроса! Я понимаю а) монады, б) монаду ввода-вывода, в) монаду Cont ( Control.Monad.Cont ), и d) монада преобразователя продолжения ContT . (И я смутно понимаю преобразователи монад в целом - хотя и недостаточно, чтобы ответить на этот вопрос.) Я понимаю, как написать программу, в которой все функции находятся в монаде Cont ( Cont ra ]), и я понимаю, как написать программу, в которой все функции находятся в объединенной монаде Cont / IO ( ContT r IO a ).

Но мне интересно как я мог бы написать программу, в которой некоторые функции находятся в комбинированной монаде Cont / IO ( ContT r IO a ), а другие функции находятся только в монаде Cont ( Контра ). По сути, я хочу написать всю программу в стиле продолжения, но использовать монаду ввода-вывода только там, где это необходимо (как и в «обычном» коде Haskell, я использую монаду ввода-вывода только там, где это необходимо).

Например, рассмотрим эти две функции , в стиле без продолжения:

foo :: Int -> IO Int
foo n = do
    let x = n + 1
    print x
    return $ bar x

bar :: Int -> Int
bar m = m * 2

Обратите внимание, что foo требует ввода-вывода, но bar является чистым. Теперь я понял, как полностью написать этот код, используя монаду продолжения, но мне также нужно было пропустить ввод-вывод через bar :

foo :: Int -> ContT r IO Int
foo n = do
    let x = n + 1
    liftIO $ print x
    bar x

bar :: Int -> ContT r IO Int
bar m = return $ m * 2

Я действительно хочу, чтобы весь мой код был в стиле продолжения , но я не хочу использовать монаду ввода-вывода для функций, которым она не требуется. По сути, я хотел бы, чтобы определял bar следующим образом:

bar :: Int -> Cont r Int
bar m = return $ m * 2

К сожалению, я не могу найти способ вызвать функцию монады Cont ra ( bar ) изнутри ContT r IO a монадная функция ( foo ). Есть ли способ «поднять» нетрансформированную монаду в трансформированную? т.е.как мне изменить строку « bar x » в foo , чтобы она могла правильно вызывать bar :: Int -> Cont r Int ?

9
задан mgiuca 6 July 2011 в 13:23
поделиться