Хаскель, где пункт не в рамках ошибки

Добрый день,

Я новичок в 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 должно быть вставлено на один уровень от имени функции.

Другие вопросы по тегам