Сегодня, работая в Coding Dojo, я попробовал следующее.
example :: IO ()
example = do input <- getLine
parsed <- parseOnly parser input
...
где parseOnly :: Parser a -> Either String a
(из attoparsec
), конечно, компилятор пожаловался, что Either ..
не IO ..
, по сути, говоря мне, что я смешиваю монады.
Конечно, это можно решить
case parseOnly parser input of .. -> ..
что как-то некрасиво, я думаю. Также я предполагаю, что у кого-то еще была эта проблема ранее, и решение, которое я думаю, связано с преобразователями монад, но последние биты я не могу собрать воедино.
Это также напомнило мне liftIO
- но я думаю, что это наоборот, что решает проблему отмены действия ввода-вывода, происходящего внутри некоторой окружающей монады (точнее, MonadIO
- скажем, например, внутри Snap
, когда кто-то хочет напечатать что-то в stdout
при получении какой-то http).
В более общем плане эта проблема кажется для Monad m1
и (другого) Monad m2
как я могу сделать что-то вроде
example = do a <- m1Action
b <- m2Action
..
IO
может находиться только в основе стека преобразователя монад. - person dfeuer   schedule 21.01.2016ExceptT IO e
— вполне разумная монада (построенная из трансформеров), к которой разумно можно поднять какEither e
, так иIO
действия. - person Daniel Wagner   schedule 21.01.2016IO
все еще находится в основании, так что вам придется завернуть все это дело вrunExceptT
или во что-то еще, но внутри все более удобно. user3237465 превратил это в ответ. - person dfeuer   schedule 21.01.2016