Нет необходимости использовать do
или liftIO
здесь.
read :: IO Config
read = Y.decodeEither' <$> BS.readFile "my_config.yaml" >>= \c -> case c of
Right x -> pure x
Left e -> error "error 123"
должно это сделать.
Однако было бы лучше использовать трансформатор ExceptT
тогда все, что вам нужно сделать, это
read :: ExceptT ParseException IO Config
read = ExceptT $ Y.decodeEither <$> BS.readFile "my_config.yaml"
Теперь вы можете делать как;
configure :: ExceptT ParseException IO ()
configure = read >>= pure . processConfig
или, как напоминает @Joseph Sible-Reinstate Monica, например
configure :: ExceptT ParseException IO ()
configure = processConfig <$> read
и если decodeEither
возвращает значение Left
, оно регистрируется и processConfig :: Config -> ()
пропускается.