Управление стеком монад - PullRequest
11 голосов
/ 08 марта 2012

Если у меня есть стек монад, скажем IO, State и Error, и функция, которая использует только IO и Error.Как можно было бы «удалить» среднюю State монаду из стека, чтобы я мог использовать свою функцию?Если бы порядок был IO, Error, State, я мог бы использовать lift для сопоставления типов, но я хочу иметь возможность использовать мою функцию, если в стеке монад содержится IO и Errorвозможно, другие монады в любом порядке.Например:

fun :: ErrorT String IO ()
fun = throwError "error"

someCode :: ErrorT String (StateT Int IO) ()
someCode = do
    -- I want to use fun here

1 Ответ

15 голосов
/ 08 марта 2012

Просто измените сигнатуру типа fun на fun :: (MonadError String m, MonadIO m) => m ().Затем он будет использоваться для любого стека монад с ошибкой String и может выполнять IO (например, ErrorT String (StateT Int IO)).

Например:

fun :: (MonadError String m, MonadIO m) => m ()
fun = do
  liftIO $ putStrLn "in fun"
  throwError "error"

someCode :: ErrorT String (StateT Int IO) ()
someCode = do
  fun
  -- whatever you want
...