Обновление летом 2017:
См. http://caniuse.com/#search=modules , новая поддержка, возможно, потребуется изменить настройки.
] Теперь, когда вещи менее расплывчаты. Чтобы сделать работу модуля, вы должны сообщить браузеру, что это модуль (другой - скрипт). Первый путь неявный, импортированный модуль всегда является модулем. Второй способ - с модулем типа
Убедитесь, что импорт и экспорт находятся только на верхнем уровне, а не внутри блока, а не внутри оператора if, а не внутри цикла и т. Д.
Также обязательно укажите полный путь (включая .js), он должен начинаться с ./
или ../
.
Устаревший ответ ниже:
Устаревший ответ: [f9]
eval
в строке модуля не будет работать. Синтаксис импорта и экспорта модуля ES2015 не поддерживается ни одним браузером в момент написания этого ответа (04/2016). Сообщение об ошибке пропущено, потому что это означает, что синтаксис поддерживается, но он вообще не поддерживается. См. Первую заметку здесь https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import
Причина в том, что спецификация для модульных погрузчиков все еще продолжается работа. См. https://whatwg.github.io/loader/#status
. Они являются инструментами, однако, для полировки или для автоматического преобразования этого синтаксиса как babel.
Во многих случаях эти глубоко вложенные углубления являются результатом глубоко вложенной проверки ошибок. Если это так, вы должны изучить MaybeT
и его старшего брата ExceptT
. Они предлагают чистый способ отделить код «что мы делаем, когда что-то пошло не так» от кода «что мы делаем, если все идет правильно». В вашем примере я могу написать:
data CustomError = IfCheckFailed | MaybeCheckFailed
main = handleErrors <=< runExceptT $ do
inFH <- liftIO $ openFile ...
outFH <- liftIO $ openFile ...
forM myList $ \item -> do
when (...) (throwError IfCheckFailed)
...
x <- liftMaybe MaybeCheckFailed ...
...
liftMaybe :: MonadError e m => e -> Maybe a -> m a
liftMaybe err = maybe (throwError err) return
handleErrors :: Either CustomError a -> IO a
handleErrors (Left err) = case err of
IfCheckFailed -> ...
MaybeCheckFailed -> ...
handleErrors (Right success) = return success
Обратите внимание, что мы все еще увеличиваем отступ в цикле forM
; но другие проверки выполняются «in-line» в main
и обрабатываются на одном уровне отступов в handleErrors
.
Вы должны сделать то же самое, что и с другим языком программирования. Функции должны быть понятны. Обычно это означает, что если он длинный, поток управления невелик, в противном случае он разделяется на отдельные функции.
Таким образом, главное может выглядеть так:
main = do
inFH <- openFile ...
outFH <- openFile ....
mapM prcoessItem myList
inFH
и outFH
всюду.
– Ørjan Johansen
8 October 2015 в 17:56
Хотя вероятнее всего есть более эффективные способы решения вашей конкретной проблемы (см., например, ответ Дэниела Вагнера), вы всегда можете использовать let
для ввода нового имени в произвольной области. Вот, по общему признанию, бессмысленная демонстрация:
main = do
inFH <- return "inf"
outFH <- return "ouf"
let subAction = do
if length inFH > 2
then print "foo"
else subSubAction
subSubAction = case outFH of
[] -> print "bar"
_ -> print "baz"
forM [1..10] $ \ item -> do
print item
subAction
let
, заключается в том, что она меняет порядок чтения - я сначала определяю часть шага, а затем приходит остальная часть потока. Мне также не нравится включать часть логического потока в имя, что является еще одной причиной, по которой я не хотел использовать where
.
– trVoldemort
8 October 2015 в 21:58