Я пересмотрел Haskell lateley и создал парсер/интерпретатор языка программирования игрушек. Использование Parsec для лексинга и синтаксического анализа и отдельный интерпретатор. Я сталкиваюсь с некоторыми проблемами с подачей результата от анализатора на мой интерпретатор и обработкой потенциальной ошибки как с интерпретатором, так и с парсером. Я получаю что-то вроде этого:Haskell: Обработка в результате Либо из вычислений
main = do
fname <- getArgs
input <- readFile (head fname)
case lparse (head fname) input of
Left msg -> putStrLn $ show msg
Right p -> case intrp p of
Left msg -> putStrLn $ show msg
Right r -> putStrLn $ show r
Это не выглядит совсем неважно. Моя проблема заключается в том, что lparse
возвращает Either ParseError [(String, Stmt)]
и itrp
возвращает тип Either ItrpError Stmt
, так что я имею реальное трудное время кормления в Right
результат от парсера к переводчику и в то же время под залог и печать возможный ParseError
или IntrpError
.
Ближайший к тому, что я хочу что-то вроде этого
main = do
fname <- getArgs
input <- readFile (head fname)
let prog = lparse (head fname) input
(putStrLn . show) (intrp <$> prog)
Но это не удивительно выход вложенной Либо и не печатать довольно либо.
Итак, есть ли какой-нибудь хороший идеологический способ Haskell для выполнения этих потоков из одного вычисления в другой и обработки ошибок (Lefts
) красивым способом без случаев гнездования?
Редактировать
добавляющие типы lparse
и itrp
lparse :: Text.Parsec.Pos.SourceName -> String -> Either Text.Parsec.Error.ParseError [([Char], Stmt)]
intrp :: [([Char], Stmt)] -> Either IntrpError Stmt
Вы, вероятно, хотите использовать 'hPutStrLn stderr' вместо' putStrLn' в 'случае Left', так что сообщение об ошибке переходит к стандартной ошибке вместо стандартного вывода. – chepner
@chepner, возможно. Я просто делаю то, что делает OP. Но да, лучше использовать 'hPutStrLn stderr' в случае сообщений об ошибках. – sham1
Невозможно использовать '>> =' в этом случае, так как типы 'lparse' и' intrp' отличаются. т.е. '' lparse :: SourceName -> String -> Или ParseError [([Char], Stmt)] '' и '' intrp :: [([Char], Stmt)] -> либо IntrpError Stmt'' – Patrik