Хаскель, где пункт не в рамках ошибки
Добрый день,
Я новичок в haskell и чертовски долго пытался скомпилировать следующее определение функции в haskell
chaseFile :: [FilePath] -- ^ path (directories to search)
-> String -- ^ base name
-> [String] -- ^ possible extensions
-> IO String -- ^ contents of file
chaseFile dirs basename exts
= do results <- mapM tryReadFile fnames
case dropWhile hasFailed results of
((Right (fc,fn)):_)
-> errLn ("Read file: "++fn) >> return fc
_ -> errLn ("Could not find file: "++basename) >> mzero
where
fnames = [d++'/':basename++'.':e | d <- dirs, e <- exts]
hasFailed (Left _) = True
hasFailed _ = False
tryReadFile fn = try ( readFile fn >>= \fc -> return (fc,fn) )
компилятор выдает следующую ошибку
*** Parser:
*** Renamer/typechecker:
..\contrib\StrategyLib-5.0\library\ChaseImports.hs:103:24:
Not in scope: `try'
Спасибо в ожидании
я добавил
import Control.Exception (try)
и я получил следующие ошибки компилятора
*** Parser:
*** Renamer/typechecker:
..\contrib\StrategyLib-5.0\library\ChaseImports.hs:96:24:
No instance for (Exception t0) arising from a use of `tryReadFile'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there are several potential instances:
instance Exception Data.Dynamic.Dynamic
-- Defined in `Data.Dynamic'
instance Exception ArithException -- Defined in `GHC.Exception'
instance Exception ErrorCall -- Defined in `GHC.Exception'
...plus 8 others
In the first argument of `mapM', namely `tryReadFile'
In a stmt of a 'do' block: results <- mapM tryReadFile fnames
In the expression:
do { results <- mapM tryReadFile fnames;
case dropWhile hasFailed results of {
((Right (fc, fn)) : _) -> errLn ("Read file: " ++ fn) >> return fc
_ -> errLn ("Could not find file: " ++ basename) >> mzero } }
Этот файл является частью проекта XsdMetz (svn checkout xsdmetz.googlecode.com/svn/trunk xsdmetz-только для чтения), написанного до 2010 года. Может ли быть так, что он не совместим с haskel 2010?
3 ответа
Учитывая ваше сообщение об ошибке Not in scope: `try'
Я предполагаю, что обсуждение макета является недоразумением, и вы скорее забыли импортировать эту функцию, которой нет в Prelude
, Поместите в верхней части вашего файла что-то вроде
import Control.Exception (try)
РЕДАКТИРОВАТЬ: Оказывается, что код предполагает старую семантику Haskell 98 / Haskell 2010 для try
, К сожалению, современный GHC скрыл это в haskell98
а также haskell2010
пакеты. Возможно, вам все равно придется использовать один из них, если вам нужно скомпилировать весь проект XsdMetz. Но в противном случае проще обойти
import System.IO.Error (tryIOError)
и заменить tryIOError
в вашем коде вместо try
,
Кроме того, вы можете использовать Control.Exception.try
, но тогда вам нужно поместить аннотацию типа где-нибудь, чтобы ограничить ее сильно перегруженный тип, чтобы он знал, какой тип исключения нужно перехватить.
Ошибка макета.
Ваше предложение where должно быть более отступом, чем имя функции. (Все привязки в предложении where должны иметь одинаковое выравнивание; вы это сделали.)
Все операторы в do должны иметь одинаковое выравнивание, и они должны иметь отступ больше, чем where. ("результаты" и "дело" должны начинаться в одном столбце.)
Все шаблоны в этом случае должны иметь одинаковое выравнивание, и они должны иметь отступ больше, чем операторы do. ("((Справа" и "_" должны начинаться в одном столбце)
Если вам не нравится чувствительность к пустому пространству, вы можете (эффективно) отказаться от правил компоновки, предоставив явные скобки и точки с запятой.
Предложение where должно быть вставлено на один уровень от имени функции.