Ошибка haskell изменяет пользовательский ввод на пользовательский тип данных в функции

handleStatements :: [Term] -> IO ()
handleStatements statements = do
    let (queries, clauses) = partition isQuery statements
    mapM_ (clausesEntailProof clauses) queries
    --apply clauses to queries and ignore result

handleArgs :: String-> IO ()
handleArgs args = do
    contents <- readFile $ args
    case parseInput contents of
      Left err -> print err
      Right statements -> handleStatements statements


main :: IO ()
main = do
  handleStatements(input)
    where input = getLine >>= (\str -> ((readIO str)::IO[Term])) 

Я получил ошибку. Не удалось сопоставить ожидаемый тип «[Term]» с фактическим типом «IO Term». Как я могу это исправить?


person kili    schedule 14.10.2020    source источник
comment
Вы не можете использовать where таким образом.   -  person Willem Van Onsem    schedule 14.10.2020
comment
@WillemVanOnsem ...почему бы и нет? Выглядит совершенно cromulent для меня. Просто пропускает >>= в теле (как в input >>= handleStatements).   -  person Daniel Wagner    schedule 14.10.2020
comment
@DanielWagner: Да, но вопрос, похоже, указывает на то, что where каким-то образом выполняет IO, а затем устанавливает результат на input. Вы действительно можете использовать input >>= handleStatements   -  person Willem Van Onsem    schedule 14.10.2020
comment
@WillemVanOnsem А, понятно. Кажется, это может относиться ко многим вещам, когда нет антецедента. Как запутанно! Спасибо, что разъяснили, что вы имели в виду.   -  person Daniel Wagner    schedule 14.10.2020


Ответы (1)


Если вы определяете input = … в предложении where, то input имеет тип IO [Term], а не [Term], поэтому вы не можете передать input в handleStatements.

Ты можешь написать:

main :: IO ()
main = do
    input <- getLine >>= (\str -> ((readIO str)::IO[Term]))
    handleStatements input

Но вы слишком все усложняете, вы можете работать с readLn :: Read a => IO a вместо этого:

main :: IO ()
main = do
    input <- readLn
    handleStatements input

или замените блок do на (>>=) :: Monad m => m a -> (a -> m b) -> m b:

main :: IO ()
main = readLn >>= handleStatements
person Willem Van Onsem    schedule 14.10.2020
comment
Спасибо!! у меня другой вопрос, есть ли у меня, например, [A-›C,B-›Q,A+D,?(C+Q)] этот ввод. Я получил ошибку *** Исключение: ошибка пользователя (Prelude.readIO: нет синтаксического анализа), я должен изменить его на список? - person kili; 14.10.2020
comment
@kili: вы уже анализируете [Term], поэтому, вероятно, это означает, что ваш парсер для одного Term не может обработать один из A->C, B->Q, A+D и т. д. или он не останавливается на запятой. - person Willem Van Onsem; 14.10.2020
comment
Спасибо, если я хочу проанализировать его в списке в соответствии с запятой, есть ли способ сделать это? или единственный способ - прочитать файл и проанализировать его? - person kili; 14.10.2020