2012-01-25 1 views
2

В Haskell GHCI я попыталсяЗАГРУЗКИ .hs в интерпретатор

Prelude> :load filename.hs 
Ok, modules loaded: Main. 

, к сожалению, я не могу запустить любой из функций, определенных в файле. Я скомпилировал файл без ошибок, но вызывающая функция выдает ошибку «Не в области: (имя функции)». Странная вещь: некоторое время раньше у меня не было проблем с этим ...

+0

Можете ли вы показать первые несколько строк своего файла? В частности, декларация 'module', если она есть. – ehird

+0

Файл компилируется отлично, и нет объявления модуля. Кажется, что он терпит неудачу, когда я нажимаю кнопку «Скомпилировать» в редакторе, а затем загружаю в ghci. – NoBugs

+1

Если у вас нет объявления модуля, по умолчанию используется 'module Main (main) where', а при компиляции доступно только функция' main'. –

ответ

3

Проблема заключается в том, что ваш редактор компиляции кода с чем-то вроде

$ ghc foo.hs 

Поскольку файл не имеет декларации модуля, GHC предполагает модуль называется Main, так как вы не указано иное и, поскольку он составляет полную программу, не экспортирует любое из определений, кроме main; то есть, он действует, как если у вас есть модуль декларации, как:

module Main (main) where 

В то время как GHCI по умолчанию для:

module Main where 

Эти module declarations указать имя модуля, который вы собираете, и какие значения экспорт. При первом объявлении из модуля выводится только main; со вторым случаем экспортируется каждое значение верхнего уровня. Значения, которые не экспортируются, не могут быть доступны извне модуля, поэтому вы получаете ошибки «не в области» в GHCi.

Непостоянное поведение GHCi, по-видимому, облегчает тестирование кода; вам не нужно иметь объявление модуля для загрузки файла и использования его определений. Решение состоит в том, чтобы положить module Main where (или некоторое другое имя модуля) в верхней части файла, что явно экспортирует все. Лично я считаю, что такое поведение запутывает, и поведение GHC и GHCi, вероятно, должно быть изменено, чтобы быть последовательным.

0

Трудно догадаться, в чем проблема. Изменились ли вы строку в верхней части файла, из чего-то вроде:

module Main where 

к чему-то вроде:

module Main (main) where 

Если вы сделали, это будет экспортировать только функцию main.

+0

Нет, я не использовал модуль. Что делает «модуль»? – NoBugs

+0

@NoBugs. Объявление модуля позволяет вам контролировать, что доступно для импорта, в другие модули или в командной строке ghci при компиляции. Я настоятельно рекомендую иметь декларацию модуля в каждом исходном файле, явная информация об экспорте помогает избежать неприятных сюрпризов. –

1

В стандарте языка указано, что если объявление модуля не указано, оно неявно module Main (main) where. Когда исходные файлы Haskell скомпилированы и затем загружаются в ghci, в объем входят только экспортированные объекты рассматриваемого модуля. В вашем случае, без объявления модуля, это только функция main.

Однако, поскольку это довольно неудобно при разработке, ghci может загрузить интерпретированный модули с более широкой областью, ср. the users' guide. Модули, загруженные в эту форму, обозначаются звездочкой перед именем модуля в приглашении, а для таких модулей не только каждый объект верхнего уровня, определенный в модуле, входит в область видимости, но также импортированные объекты, все в области сверху, уровень модуля также доступен в командной строке ghci, когда модуль загружается в эту форму.

Это позволяет удобно тестировать функции в разработке и, следовательно, является хорошей штукой.С другой стороны, как справедливо упоминает @ehird, разница в поведении может быть запутанной и, следовательно, плохой.

В целом, я думаю, что преимущества расширенного диапазона ghci для *Module s перевешивают непоследовательность.

0

Возможно, вы скомпилировали модуль до того, как в каталоге находятся файлы .o и .hi. Когда GHCi найдет это, он по умолчанию загрузит модуль в скомпилированный режим, что означает, что только материал, экспортируемый из модуля, находится в области видимости.

Если вы не указали объявление модуля, по умолчанию это будет только main, так как объявление модуля по умолчанию - module Main (main) where. Это также название Main.

Вы можете сказать, что это происходит из подсказки. Как правило, при загрузке модуля будет выглядеть следующим образом:

Prelude> :load Foo.hs 
[1 of 1] Compiling Main    (Foo.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> 

Звездочка перед тем Main означает, что модуль работает в режиме интерпретации, и что все, что в нем находится в области, в том числе вещи, импортируемой из других модулей. Однако, если бы я только что собрали Foo.hs, а затем попытался загрузить его в GHCi, я бы вместо того, чтобы увидеть что-то вроде этого:

Prelude> :load Foo.hs 
Ok, modules loaded: Main. 
Prelude Main> 

Вы можете принудительно истолковано режим предваряя имя файла со звездочкой:

Prelude> :load *Foo.hs 
[1 of 1] Compiling Main    (Foo.hs, interpreted) 
Ok, modules loaded: Main. 
*Main> 
0

Не уверен, что это поможет, но у меня была такая же проблема.

Выключает виртуальную версию, в которой я запускал GHCI, было вне пространства, поэтому, когда я сохранил файлы, они были пустыми.

Попытка загрузить файл выглядела так, как будто это удалось (Whatever.hs, интерпретировано) - но у меня такая же ошибка.