Как читать файл в блоке do - PullRequest
3 голосов
/ 09 июля 2020

Я изучаю Haskell и пытаюсь понять, почему я получаю ошибку в следующем фрагменте кода. Я пытаюсь определить функцию, которая может читать файл в заданном месте и выполнять с ним какую-то функцию, но у нее есть ошибка, и, боюсь, я не могу разобраться.

Я представляю, что делаю что-то глупое, но не могу понять, что именно; может кто подскажет?

readAndProcessFile ::  String -> (String -> a) -> a
readAndProcessFile l f = do
    contents <- readFile l -- error here
    let result = f contents
    return result

Я получаю сообщение об ошибке:

Происходит проверка: невозможно построить бесконечный тип: a ~ IO a

В stmt блока 'do': contents <- readFile l </p>

В выражении:

do contents <- readFile l
   let result = (f contents)
   return result

В уравнении для readAndProcessFile:

  readAndProcessFile l f
    = do contents <- readFile l
         let result = ...
         return result

• Соответствующие привязки включают

f :: String -> a
readAndProcessFile :: String -> (String -> a) -> a

1 Ответ

5 голосов
/ 09 июля 2020

тип readAndProcessFile - String -> (String -> a) -> IO a. Действительно, вы используете блок do, это означает, что это монади c. То, что вы здесь в основном пишете, это readFile >>= \contents -> let result = f contents in return result. Кроме того, readFile превращает это в IO.

Вы можете упростить выражение, используя <$> :: Functor f => (a -> b) -> f a -> f b

readAndProcessFile :: FilePath -> (String -> a) -> <b>IO</b> a
readAndProcessFile l f = f <b><$></b> readFile l
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...