Я пытаюсь написать простую функцию для безопасного чтения файла (если он существует) и ничего не делать, если файл не существует:Haskell Safe IO
safeRead :: String -> IO()
safeRead path = readFile path `catch` handleExists
where handleExists e
| isDoesNotExistError e = return()
| otherwise = throwIO e
Это терпит неудачу во время компиляции с
Couldn't match type ‘[Char]’ with ‘()’
Expected type: IO()
Actual type: IO String
In the first argument of ‘catch’, namely ‘readFile path’
In the expression: readFile path `catch` handleExists
Это имеет смысл с :t readFile
is readFile :: FilePath -> IO String
. например, функция, которая возвращает IO String
(и IO String
не то же самое, как IO()
)
Изменения подписи String -> IO String
Couldn't match type ‘()’ with ‘[Char]’
Expected type: IOError -> IO String
Actual type: IOError -> IO()
In the second argument of ‘catch’, namely ‘handleExists’
In the expression: readFile path `catch` handleExists
Который также имеет смысл, поскольку handleExists имеет тип IO()
Чтобы сохранить весь поиск, улов импортируется с: import Control.Exception
подпись улова: catch :: Exception e => IO a -> (e -> IO a) -> IO a
Мой настоящий вопрос: как я могу написать такой безопасный, гибкий код в Haskell? Более конкретно, каково было бы изменение, которое я должен был бы сделать для этой функции, чтобы он обрабатывал как случай успеха, так и случай сбоя?
ваш код скомпилирует для меня создание 'isDoesNotexistError' всегда возвращает true, поэтому проблема может быть в противном случае? – Netwave
yep, только что отмеченный, throwIO возвращает 'IO a', а не' IO() ' – Netwave
, мне кажется, что подпись, которую вы ищете, это' String -> IO (Maybe String) ' – Carsten