Spec-Zone.ru › Haskell 9

5.2. Предупреждения и проверка корректности

GHC предоставляет ряд параметров, позволяющих выбрать типы нефакатальных сообщений об ошибках, также известных как предупреждения, которые могут генерироваться во время компиляции. Одни параметры управляют отдельными предупреждениями, другие — группами предупреждений. Используйте -W⟨wflag⟩, чтобы включить отдельное предупреждение или группу, либо -Wno-⟨wflag⟩, чтобы отключить её. Используйте -Werror, чтобы сделать все предупреждения фатальными ошибками, или -Werror=⟨wflag⟩, чтобы сделать ошибкой конкретное предупреждение. Отменить это можно с помощью -Wwarn, чтобы сделать все предупреждения нефатальными, или -Wwarn=⟨wflag⟩, чтобы сделать нефатальным конкретное предупреждение.

Примечание

В GHC < 8 синтаксис для -W⟨wflag⟩ был таким: -fwarn-⟨wflag⟩ (например, -fwarn-incomplete-patterns). Это написание считается устаревшим, но по-прежнему принимается для обратной совместимости. Аналогично, раньше -Wno-⟨wflag⟩ записывался как fno-warn-⟨wflag⟩ (например, -fno-warn-incomplete-patterns).

5.2.1. Группы предупреждений

Следующие флаги позволяют легко выбрать стандартные «пакеты» предупреждений. Их можно отменить с помощью -Wno-⟨group⟩, которая действует так же, как -Wno-... для каждого отдельного предупреждения в группе.

-Wdefault
Начиная с:

8.0

По умолчанию включён стандартный набор предупреждений, которые, как правило, могут указывать на ошибки в вашей программе. В него входят:

  • -Woverlapping-patterns
  • -Wwarnings-deprecations
  • -Wdeprecations
  • -Wdeprecated-flags
  • -Wunrecognised-pragmas
  • -Wduplicate-exports
  • -Wderiving-defaults
  • -Woverflowed-literals
  • -Wempty-enumerations
  • -Wmissing-fields
  • -Wmissing-methods
  • -Wwrong-do-bind
  • -Wsimplifiable-class-constraints
  • -Wtyped-holes
  • -Wdeferred-type-errors
  • -Wpartial-type-signatures
  • -Wunsupported-calling-conventions
  • -Wdodgy-foreign-imports
  • -Winline-rule-shadowing
  • -Wunsupported-llvm-version
  • -Wmissed-extra-shared-lib
  • -Wtabs
  • -Wunrecognised-warning-flags
  • -Winaccessible-code
  • -Wstar-binder
  • -Wstar-is-type
  • -Woperator-whitespace-ext-conflict
  • -Wambiguous-fields
  • -Wunicode-bidirectional-format-characters
  • -Wgadt-mono-local-binds
  • -Wtype-equality-requires-operators
  • -Wtype-equality-out-of-scope
  • -Wbadly-levelled-types
  • -Winconsistent-flags
  • -Wnoncanonical-monoid-instances
  • -Wnoncanonical-monad-instances
  • -Wimplicit-rhs-quantification
  • -Wunusable-unpack-pragmas
-W

Включает стандартные предупреждения, а также следующие:

  • -Wunused-binds
  • -Wunused-matches
  • -Wunused-foralls
  • -Wunused-imports
  • -Wincomplete-patterns
  • -Wdodgy-exports
  • -Wdodgy-imports
  • -Wunbanged-strict-patterns
-Wextra

Синоним для -W

-Wall

Включает все параметры предупреждений, указывающих на потенциально подозрительный код. К ним относятся все предупреждения из -Wextra, а также:

  • -Whi-shadowing
  • -Wincomplete-record-updates
  • -Wincomplete-record-selectors
  • -Wincomplete-uni-patterns
  • -Wmissing-pattern-synonym-signatures
  • -Wmissing-signatures
  • -Wname-shadowing
  • -Worphans
  • -Wredundant-record-wildcards
  • -Wstar-is-type
  • -Wtrustworthy-safe
  • -Wtype-defaults
  • -Wunused-do-bind
  • -Wunused-record-wildcards
  • -Wincomplete-export-warnings
  • -Wderiving-typeable
-Weverything
Начиная с:

8.0

Включает все предупреждения, поддерживаемые компилятором.

-Wcompat
Начиная с:

8.0

Включает предупреждения, которые в будущем будут включены по умолчанию, но пока остаются отключёнными при обычной компиляции. Это позволяет авторам библиотек, стремящимся обеспечить совместимость кода с будущими версиями, адаптироваться к новым возможностям ещё до появления соответствующих предупреждений.

Сейчас этот параметр включает:

  • -Wpattern-namespace-specifier
-w

Отключает все предупреждения, включая стандартные и те, которые не включает -Wall.

-Wnot

Устаревший синоним для -w

При выводе предупреждения показывается управляющий им флаг предупреждения, но при необходимости можно также показать и группу:

-fshow-warning-groups
По умолчанию:

off

При указании флага, управляющего предупреждением, также показывать соответствующие флаги групп предупреждений, в которые оно входит.

5.2.2. Обработка предупреждений как фатальных ошибок

Эти параметры управляют тем, какие предупреждения считаются фатальными и приводят к прерыванию компиляции.

-Werror
Начиная с:

6.8 (-Wwarn)

Делает любое предупреждение фатальной ошибкой. Это полезно, чтобы не пропустить предупреждения при пакетной компиляции. Чтобы отменить -Werror и перестать считать предупреждения ошибками, используйте -Wwarn; чтобы перестать считать ошибками отдельные предупреждения, используйте -Wwarn=⟨wflag⟩.

-Werror=⟨wflag⟩
Подразумевает:

-W⟨wflag⟩

Делает конкретное предупреждение фатальной ошибкой. Если предупреждение ещё не включено, оно будет включено. Этот параметр можно отменить с помощью -Wwarn=⟨wflag⟩.

-Werror=⟨group⟩ действует так же, как -Werror=... для каждого флага предупреждения в группе (например, -Werror=compat превратит все предупреждения группы -Wcompat в фатальные ошибки).

-Wwarn

Предупреждения считаются только предупреждениями, а не ошибками. Это поведение используется по умолчанию, но этот параметр может быть полезен для отмены флага -Werror.

-Wwarn=⟨wflag⟩

Заставляет считать конкретное предупреждение обычным предупреждением, а не фатальной ошибкой.

Обратите внимание: этот параметр не полностью отменяет действие -Werror=⟨wflag⟩ — предупреждение всё равно останется включённым.

-Wwarn=⟨group⟩ действует так же, как -Wwarn=... для каждого флага предупреждения в группе (например, -Wwarn=compat пометит все предупреждения группы -Wcompat как нефатальные).

-Wno-error=⟨wflag⟩

Альтернативное написание для -Wwarn=⟨wflag⟩.

5.2.3. Индивидуальные параметры предупреждений

Полный список параметров предупреждений приведён ниже. Чтобы отключить какое-либо предупреждение, просто укажите соответствующий параметр -Wno-... в командной строке. Для обратной совместимости с версиями GHC до 8.0 всеми этими предупреждениями по-прежнему можно управлять с помощью -f(no-)warn-* вместо -W(no-)*.

-Wunrecognised-warning-flags
Начиная с:

8.0

По умолчанию:

включено

Включает предупреждения, если компилятор встречает нераспознанный флаг -W....

-Wcompat-unqualified-imports
Начиная с:

8.10

Это предупреждение устарело. Начиная с GHC 9.12 оно больше не действует.

-Wprepositive-qualified-module
Начиная с:

8.10

Обычно импорты квалифицируются препозитивно: import qualified M. С помощью ImportQualifiedPost ключевое слово qualified можно использовать после имени модуля. Например: import M qualified. Это предупреждение выдаётся при использовании первого, препозитивного синтаксиса.

-Wtyped-holes
Начиная с:

7.8

По умолчанию:

включено

Определяет, сообщает ли компилятор предупреждения о типизированных дырах. Не действует, если только ошибки типизированных дыр не откладываются до времени выполнения. См. Типизированные дыры и Откладывание ошибок типов до времени выполнения.

-Wdeferred-type-errors
Начиная с:

8.0

По умолчанию:

включено

Вызывает выдачу предупреждения, если ошибка типа отложена до времени выполнения. См. Откладывание ошибок типов до времени выполнения.

-Wdeferred-out-of-scope-variables
Начиная с:

8.0

Выдаёт предупреждение при обнаружении отложенной переменной, находящейся вне области видимости. См. Откладывание ошибок типов до времени выполнения.

-Wpartial-type-signatures
Начиная с:

7.10

По умолчанию:

включено

Определяет, сообщает ли компилятор о дырах в частичных сигнатурах типов как о предупреждениях. Не действует, если не включено расширение PartialTypeSignatures, которое определяет, следует ли выдавать ошибки для дыр в типах. См. Частичные сигнатуры типов.

-fhelpful-errors
Начиная с:

7.4

По умолчанию:

включено

Если имя или пакет не найдены в области видимости, предлагает варианты имени или пакета, которые, возможно, имелись в виду.

-Wunrecognised-pragmas
Начиная с:

6.10

По умолчанию:

включено

Вызывает выдачу предупреждения при использовании прагмы, не распознаваемой GHC. Помимо прагм, используемых самим GHC, GHC также распознаёт прагмы, которые, как известно, используются другими инструментами, например OPTIONS_HUGS и DERIVE.

-Wmisplaced-pragmas
Начиная с:

9.4

По умолчанию:

включено

Выдаёт предупреждение, если прагма, которая должна находиться только в заголовке модуля, например прагма LANGUAGE или OPTIONS_GHC, вместо этого расположена в теле модуля.

-Wdeprecated-pragmas
Начиная с:

9.14

По умолчанию:

включено

Выдаёт предупреждение при использовании устаревшей формы прагмы SPECIALISE с несколькими разделёнными запятыми сигнатурами типов (она устарела и запланирована к удалению в GHC 9.18).

-Wrule-lhs-equalities
Начиная с:

9.14

По умолчанию:

включено

Если GHC встречает RULE, левая часть которого порождает ограничения равенства, над которыми предыдущие версии GHC (<= 9.12) разрешали квантифицировать, GHC вместо этого отбросит правило и выдаст предупреждение; выдача предупреждения управляется этим флагом.

Это предупреждение призвано показать, что правила RULES, создаваемые предыдущими версиями GHC в таких случаях, никогда не могли сработать.

-Wmissed-specialisations
Начиная с:

8.0

По умолчанию:

выключено

Выдаёт предупреждение, если GHC не может специализировать функцию с перегрузкой, обычно потому, что функции нужна прагма INLINABLE. Сообщает о случаях, возникающих при специализации импортированной функции.

Эта форма предназначена для выявления случаев, когда импортированную функцию пометили как INLINABLE (предположительно, чтобы включить специализацию), но её не удаётся специализировать, поскольку она вызывает другие функции, которые сами не специализированы.

Обратите внимание, что при использовании с -Werror это предупреждение не приводит к ошибкам.

-Wmissed-specializations

Псевдоним для -Wmissed-specialisations

-Wall-missed-specialisations
Начиная с:

8.0

По умолчанию:

выключено

Выдаёт предупреждение, если GHC не может специализировать функцию с перегрузкой, обычно потому, что функции нужна прагма INLINABLE. Сообщает обо всех таких случаях.

Обратите внимание, что при использовании с -Werror это предупреждение не приводит к ошибкам.

-Wall-missed-specializations

Псевдоним для -Wall-missed-specialisations

-Wuseless-specialisations
Начиная с:

9.14

По умолчанию:

включено

Выдаёт предупреждение, если GHC обнаруживает бесполезную прагму SPECIALISE, например прагму SPECIALISE для функции без перегрузки, как в {-# SPECIALISE id :: Int -> Int #-}.

-Wuseless-specializations

Псевдоним для -Wuseless-specialisations

-Wextended-warnings
Начиная с:

9.8.1

По умолчанию:

включено

Вызывает выдачу предупреждения при использовании модуля, функции или типа с прагмой WARNING или DEPRECATED независимо от категории, которая может быть связана с прагмой. Подробнее о прагмах см. Прагмы WARNING и DEPRECATED. Этот флаг включает -Wdeprecations и все флаги -Wx-⟨category⟩.

-Wx-⟨category⟩
Начиная с:

9.8.1

По умолчанию:

включено

Вызывает выдачу предупреждения при использовании модуля, функции или типа с прагмой WARNING in "x-⟨category⟩". Подробнее о прагмах см. Прагмы WARNING и DEPRECATED.

-Wdeprecations
По умолчанию:

включено

Вызывает выдачу предупреждения при использовании модуля, функции или типа с прагмой DEPRECATED pragma либо прагмой WARNING с категорией deprecated. Подробнее о прагмах см. Прагмы WARNING и DEPRECATED.

-Wwarnings-deprecations
Начиная с:

6.10

По умолчанию:

включено

Вызывает выдачу предупреждения при использовании модуля, функции или типа с прагмой DEPRECATED pragma либо прагмой WARNING с категорией deprecated. Подробнее о прагмах см. Прагмы WARNING и DEPRECATED. Псевдоним для -Wdeprecations.

-Wnoncanonical-monad-instances
Начиная с:

8.0

По умолчанию:

включено

Выдаёт предупреждение при обнаружении нек canonical объявлений экземпляров Applicative или Monad.

При включённом предупреждении проверяются следующие условия:

В объявлениях экземпляров Monad выдаётся предупреждение, если не выполняется хотя бы одно из следующих условий:

  • Если определён return, он должен быть каноническим (то есть return = pure).
  • Если определён (>>), он должен быть каноническим (то есть (>>) = (*>)).

Кроме того, в объявлениях экземпляров Applicative:

  • Выдаётся предупреждение, если pure определён в обратном порядке (то есть pure = return).
  • Выдаётся предупреждение, если (*>) определён в обратном порядке (то есть (*>) = (>>)).
-Wnoncanonical-monadfail-instances
Начиная с:

8.0

Это предупреждение устарело. Начиная с GHC 8.8 оно больше не действует. Оно использовалось в переходный период после принятия предложения MonadFail, чтобы обнаруживать случаи, когда экземпляр класса Monad был определён не через MonadFail или когда экземпляр MonadFail был определён в обратном порядке с использованием метода из Monad.

-Wnoncanonical-monoid-instances
Начиная с:

8.0

По умолчанию:

включено

Выдаёт предупреждение при обнаружении нек canonical объявлений экземпляров Semigroup или Monoid.

При включённом предупреждении проверяются следующие условия:

В объявлениях экземпляров Monoid выдаётся предупреждение, если не выполняется следующее условие:

  • Если определён mappend, он должен быть каноническим (то есть mappend = (Data.Semigroup.<>)).

Кроме того, в объявлениях экземпляров Semigroup:

  • Выдаётся предупреждение, если (<>) определён в обратном порядке (то есть (<>) = mappend).
-Wmissing-monadfail-instances
Начиная с:

8.0

Это предупреждение устарело. Начиная с GHC 8.8 оно больше не действует. Оно использовалось в переходный период после принятия предложения MonadFail, чтобы выдавать предупреждение, когда в блоке do используется неудачное сопоставление с образцом без экземпляра MonadFail.

-Wsemigroup
Начиная с:

8.0

Это предупреждение устарело. Начиная с GHC 9.8 оно больше не действует. Оно использовалось в переходный период после принятия предложения semigroup, чтобы выдавать предупреждение, если экземпляр Monoid не являлся экземпляром Semigroup или если пользовательский локальный оператор (<>) мог конфликтовать с (<>), который теперь экспортируется из Prelude.

-Wdeprecated-flags
Начиная с:

6.10

По умолчанию:

включено

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

-Wunsupported-calling-conventions
Начиная с:

7.6

Вызывает выдачу предупреждения для foreign-объявлений, в которых используются неподдерживаемые соглашения о вызовах. В частности, если используется соглашение о вызовах stdcall, оно будет считаться ccall.

-Wdodgy-foreign-imports
Начиная с:

6.10

Вызывает выдачу предупреждения для foreign-импортов следующего вида:

foreign import "f" f :: FunPtr t

поскольку, вероятно, следует использовать

foreign import "&f" f :: FunPtr t

Первая форма объявляет, что f — это (чистая) функция C, которая не принимает аргументов и возвращает указатель на функцию C типа t, тогда как вторая форма объявляет, что f сама является функцией C типа t. Первое объявление обычно является ошибкой, которую трудно отлаживать, поскольку она приводит к аварийному завершению программы, поэтому и выдаётся это предупреждение.

-Wdodgy-exports
Начиная с:

6.12

Вызывает выдачу предупреждения, если экспортируется тип данных T со всеми конструкторами, то есть T(..), хотя на самом деле это всего лишь синоним типа.

Также вызывает выдачу предупреждения при реэкспорте модуля, который ничего не экспортирует.

-Wdodgy-imports
Начиная с:

6.8

Вызывает выдачу предупреждения в следующих случаях:

  • Когда тип данных T импортируется со всеми конструкторами, то есть T(..), но был экспортирован абстрактно, то есть T.
  • Когда оператор import скрывает сущность, которая не экспортируется.
-Woverflowed-literals
Начиная с:

7.8

Вызывает выдачу предупреждения, если литерал переполняет диапазон, например 300 :: Word8.

-Wempty-enumerations
Начиная с:

7.8

Вызывает выдачу предупреждения, если перечисление пусто, например [5 .. 3].

-Wderiving-defaults
Начиная с:

8.10

Вызывает предупреждение, если включены расширения DeriveAnyClass и GeneralizedNewtypeDeriving, но явная стратегия deriving не указана. Например, это вызовет предупреждение:

class C a
newtype T a = MkT a deriving C
-Wduplicate-constraints
Начиная с:

7.8

Заставляет компилятор выдавать предупреждение о повторяющихся ограничениях в сигнатуре типа. Например:

f :: (Eq a, Show a, Eq a) => a -> a

В предупреждении будет указано повторяющееся ограничение Eq a.

Этот параметр устарел; вместо него рекомендуется использовать -Wredundant-constraints.

-Wredundant-constraints
Начиная с:

8.0

Заставляет компилятор выдавать предупреждение об избыточных ограничениях в сигнатуре типа. В частности:

  • Избыточное ограничение непосредственно в сигнатуре типа:

    f :: (Eq a, Ord a) => a -> a
    

    В предупреждении будет указано избыточное ограничение Eq a: оно поглощается ограничением Ord a.

  • Ограничение в сигнатуре типа не используется в охватываемом им коде:

    f :: Eq a => a -> a -> Bool
    f x y = True
    

    В предупреждении будет указано избыточное ограничение Eq a: оно не используется определением f.)

Аналогичные предупреждения выдаются для избыточных ограничений в объявлении экземпляра.

При включении этого параметра предупреждение можно отключить для отдельного модуля с помощью -Wno-redundant-constraints. Иногда может быть нужно, чтобы у функции была более ограниченная сигнатура, чем требуется, например, чтобы оставить себе возможность изменить реализацию без изменения API. В таком случае предупреждение можно отключить для отдельной функции, используя вызов в неиспользуемом связывании. Например:

f :: Eq a => a -> a -> Bool
f x y = True
where
    _ = x == x  -- Suppress the redundant-constraint warning for (Eq a)

Здесь вызов (==) заставляет GHC считать ограничение (Eq a) необходимым, поэтому предупреждение не выдаётся.

-Wduplicate-exports
Начиная с:

как минимум 5.04

По умолчанию:

включено

Заставляет компилятор выдавать предупреждения о повторяющихся элементах в списках экспорта. Это полезно при работе с большими списками экспорта, если вы хотите избежать дальнейшего экспорта определения после удаления одного из упоминаний о нём в списке.

-Whi-shadowing
Начиная с:

как минимум 5.04, устарел

Вызывает выдачу компилятором предупреждения, если модуль или файл интерфейса в текущем каталоге затеняет одноимённый модуль в библиотеке или другом каталоге.

Этот флаг был реализован некорректно и теперь устарел. Он будет удалён в одной из следующих версий GHC.

-Widentities
Начиная с:

7.2

Вызывает выдачу компилятором предупреждения, если числовое преобразование из Prelude преобразует тип T в тот же тип T; вероятно, такие вызовы ничего не делают и их можно опустить. Проверяются функции: toInteger, toRational, fromIntegral и realToFrac.

-Wimplicit-kind-vars
Начиная с:

8.6

Это предупреждение устарело. Начиная с GHC 8.10 оно больше не действует. Оно использовалось для обнаружения неявной квантификации переменной рода. Например, следующий код вызвал бы предупреждение:

f :: forall (a :: k). Proxy a

Теперь это ошибка. Исправить её можно, явно квантифицировав по k:

f :: forall k (a :: k). Proxy a

или

f :: forall {k} (a :: k). Proxy a
-Wimplicit-lift
Начиная с:

9.2

Цитаты Template Haskell, ссылающиеся на локальные переменные, связанные за пределами цитаты, неявно преобразуются так, чтобы использовать lift. Например, f x = [| reverse x |] преобразуется в f x = [| reverse $(lift x) |]). Этот флаг выдаёт предупреждение при каждом таком неявном добавлении lift. Это может быть полезно при отладке более сложных многоэтапных программ, в которых неявный lift может случайно скрыть переменную, использованную не на том этапе.

-Wimplicit-prelude
Начиная с:

6.8

По умолчанию:

выключено

Заставляет компилятор выдавать предупреждение при неявном импорте Prelude. Это происходит, если модуль Prelude не импортирован явно строкой import ... Prelude ... и этот неявный импорт не отключён (с помощью NoImplicitPrelude или прагмы LANGUAGE NoImplicitPrelude).

Обратите внимание: предупреждение не выдаётся для синтаксических конструкций, которые неявно ссылаются на Prelude, даже если NoImplicitPrelude изменило бы то, ссылаются ли они на Prelude. Например, предупреждение не выдаётся, когда 368 означает Prelude.fromInteger (368::Prelude.Integer) (где Prelude ссылается на настоящий модуль Prelude независимо от импортов компилируемого модуля).

-Wincomplete-patterns
Начиная с:

5.04

Параметр -Wincomplete-patterns выдаёт предупреждения для мест, где сопоставление с образцом может завершиться неудачей во время выполнения. Приведённая ниже функция g завершится неудачей при применении к непустым спискам, поэтому при включённом параметре -Wincomplete-patterns компилятор выдаст предупреждение.

g [] = 2

Этот параметр выключен по умолчанию, поскольку он может выдавать слишком много предупреждений и не всегда указывает на ошибку в программе. Тем не менее, обычно считается хорошей практикой обрабатывать все случаи в функциях; этот параметр включается флагом -W.

-Wincomplete-uni-patterns
Начиная с:

7.2

Флаг -Wincomplete-uni-patterns похож на -Wincomplete-patterns, но применяется только к лямбда-выражениям и связываниям с образцом — конструкциям, допускающим только один образец:

h = \[] -> 2
Just k = f y

Кроме того, этот флаг применяется к ленивым образцам, поскольку они являются синтаксическим сахаром для связываний с образцом. Например, f ~(Just x) = (x,x) эквивалентно f y = let Just x = y in (x,x).

-fmax-pmcheck-models=⟨n⟩
С версии:

8.10

По умолчанию:

30

Средство проверки сопоставления с образцом работает, присваивая каждому образцу символьные значения. Каждое такое присваивание называется «моделью». Каждая ветвь сопоставления с образцом может приводить к нескольким разбиениям этой модели, описывающим различные способы, которыми сопоставление с образцом может завершиться неудачей. Например, при сопоставлении x с Just 4 каждая входящая модель сопоставления разбивается на две непокрытые подмодели: одну, в которой x — это Nothing, и другую, в которой x — это Just y, но y не является 4.

В некоторых случаях это может приводить к экспоненциальной зависимости от арности образца и количества охранных выражений. Ограничение -fmax-pmcheck-models=⟨n⟩ гарантирует полиномиальный рост относительно количества образцов, отбрасывая уточнённую информацию, полученную в результате частично успешного сопоставления. В приведённом выше примере при ограничении, равном 1, проверка следующей ветви продолжилась бы с исходной, неуточнённой моделью.

-Wincomplete-record-updates
С версии:

6.4

Применение функции f ниже к Bar завершится неудачей, поэтому компилятор выдаст предупреждение, если включён параметр -Wincomplete-record-updates.

data Foo = Foo { x :: Int }
         | Bar

f :: Foo -> Foo
f foo = foo { x = 6 }

Этот параметр по умолчанию отключён, поскольку он может создавать слишком много предупреждений, которые часто не указывают на ошибку в программе.

-Wincomplete-record-selectors
С версии:

9.10

При применении селектора записи к конструктору, который не содержит соответствующего поля, возникнет ошибка. Например:

data T = T1 | T2 { x :: Int }

f :: T -> Int
f a = x a -- `f T1` will fail

g1 :: HasField "x" t Int => t -> Int
g1 a = 1 + getField @"x" a

g2 :: T -> Int
g2 a = g1 a + 2 -- `g2 T1` will fail as well

Это предупреждение сообщается о подобных случаях. Оно также учитывает случаи, обработанные ранее сопоставлением с образцом. Например:

d :: T -> Int
d T1 = 0
d a = x a -- would not warn
-Wmissing-deriving-strategies
С версии:

8.8.1

По умолчанию:

выключено

Тип данных ниже выводит экземпляр класса типов Eq, но не указывает стратегию. Если включён параметр -Wmissing-deriving-strategies, компилятор выдаст предупреждение.

data Foo a = Foo a
  deriving (Eq)

Компилятор предупредит, что в объявлении deriving не указана стратегия. В предлагаемом исправлении будут показаны предполагаемые стратегии вывода.

Если предупреждение включено, но расширение DerivingStrategies не включено, компилятор предложит включить расширение DerivingStrategies.

-Wmissing-fields
С версии:

как минимум 5.04

Этот параметр включён по умолчанию и выдаёт предупреждение, если при создании конструктора с именованными полями отсутствуют инициализаторы для одного или нескольких полей. Это не является ошибкой (отсутствующие поля инициализируются неопределёнными значениями), но часто указывает на ошибку программиста.

-Wmissing-export-lists
С версии:

8.4

Этот параметр выдаёт предупреждение, если модуль объявлен без явного списка экспорта. Например:

module M where

  p x = x

Параметр -Wmissing-export-lists предупредит, что в M не объявлен список экспорта. Объявление явного списка экспорта для M позволяет GHC выполнять анализ мёртвого кода, предотвращает случайный экспорт имён и может упростить такие оптимизации, как встраивание.

-Wmissing-import-lists
С версии:

7.0

Этот параметр выдаёт предупреждение, если используется неквалифицированное объявление import, в котором явно не перечислены сущности, добавляемые в область видимости. Например:

module M where
  import X( f )
  import Y
  import qualified Z
  p x = f x x

Параметр -Wmissing-import-lists предупредит об импорте Y, но не X. Если позднее в модуль Y добавить экспорт (например) f, ссылка на f в M станет неоднозначной. Предупреждение об импорте Z не выдаётся, поскольку расширение списка экспортируемых сущностей из Z вряд ли приведёт к неоднозначности в M.

-Wmissing-methods
С версии:

как минимум 5.04

По умолчанию:

включено

Этот параметр выдаёт предупреждение, если в объявлении экземпляра отсутствует один или несколько методов, для которых в соответствующем объявлении класса не задана реализация по умолчанию.

Прагма MINIMAL позволяет изменить, какая комбинация методов требуется для экземпляров определённого класса. См. прагму MINIMAL.

-Wmissing-signatures
С версии:

как минимум 5.04

По умолчанию:

выключено

Чтобы GHC проверял наличие сигнатуры типа у каждой функции или значения верхнего уровня, используйте параметр -Wmissing-signatures. В рамках предупреждения GHC также сообщает выведенный тип.

-Wmissing-exported-sigs
С версии:

7.10

Этот параметр устарел; вместо него рекомендуется использовать -Wmissing-exported-signatures.

-Wmissing-exported-signatures
С версии:

8.0

По умолчанию:

выключено

Чтобы GHC проверял наличие сигнатуры типа у каждой экспортируемой функции или значения верхнего уровня, но не проверял неэкспортируемые значения, используйте параметр -Wmissing-exported-signatures. Если этот параметр используется вместе с -Wmissing-signatures, сигнатура типа должна быть у каждой функции или значения верхнего уровня. В рамках предупреждения GHC также сообщает выведенный тип.

-Wmissing-local-sigs
С версии:

7.0

Этот параметр устарел; вместо него рекомендуется использовать -Wmissing-local-signatures.

-Wmissing-local-signatures
С версии:

8.0

Если использовать параметр -Wmissing-local-signatures, GHC будет выдавать предупреждения обо всех полиморфных локальных связях. В рамках предупреждения GHC также сообщает выведенный тип. По умолчанию параметр отключён.

-Wmissing-pattern-synonym-signatures
С версии:

8.0

По умолчанию:

выключено

Чтобы GHC проверял наличие сигнатуры типа у каждого синонима образца, используйте параметр -Wmissing-pattern-synonym-signatures. Если этот параметр используется вместе с -Wmissing-exported-signatures, сигнатура типа требуется только для экспортируемых синонимов образцов. GHC также сообщает выведенный тип.

-Wmissing-kind-signatures
С версии:

9.2

По умолчанию:

выключено

Чтобы GHC проверял наличие у каждого объявления типа данных, семейства типов или класса типов отдельной сигнатуры рода или CUSK, используйте параметр -Wmissing-kind-signatures. Род можно задать с помощью StandaloneKindSignatures или CUSKs.

Обратите внимание, что -Wmissing-kind-signatures не выдаёт предупреждения о связанных семействах типов, поскольку GHC считает, что объявление связанного семейства типов имеет CUSK, если охватывающий его класс имеет CUSK. (Подробнее об этом см. в разделе Полные пользовательские сигнатуры рода и полиморфная рекурсия.) Поэтому для устранения предупреждений о связанных семействах типов достаточно задать отдельную сигнатуру рода или CUSK для родительского класса.

-Wmissing-poly-kind-signatures
С версии:

9.8

По умолчанию:

выключено

Это ограниченный вариант параметра -Wmissing-kind-signatures.

Предупреждение выдаётся, если объявление определяет конструктор типа без отдельной сигнатуры рода, а выведенный род является полиморфным (что происходит с -PolyKinds. Например:

data T a = MkT (a -> Int)    -- T :: Type -> Type
                             -- Not polymorphic, hence no warning
data W f a = MkW (f a)       -- W :: forall k. (k->Type) -> k -> Type
                             -- Polymorphic, hence warning!

Этот параметр полезен для обнаружения случайно полиморфных по роду типов или для явного указания такой полиморфности, не требуя сигнатуры рода для каждого типа.

-Wmissing-exported-pattern-synonym-signatures
По умолчанию:

выключено

Чтобы GHC проверял наличие сигнатуры типа у каждого экспортируемого синонима образца, но не проверял неэкспортируемые синонимы образцов, используйте параметр -Wmissing-exported-pattern-synonym-signatures. Если этот параметр используется вместе с -Wmissing-pattern-synonym-signatures, сигнатура типа требуется для каждого синонима образца. В рамках предупреждения GHC также сообщает выведенный тип.

-Wname-shadowing
С версии:

как минимум 5.04

Этот параметр включает предупреждение о случаях, когда значение во внутренней области видимости имеет то же имя, что и значение во внешней области, то есть внутреннее значение затеняет внешнее. Это позволяет обнаруживать опечатки, которые могут привести к трудноуловимым ошибкам, например непреднамеренный захват того, что должно было быть рекурсивным вызовом в f = ... let f = id in ... f ....

Для имён, начинающихся с подчёркивания, предупреждение не выдаётся. Например:

f x = do { _ignore <- this; _ignore <- that; return (the other) }
-Worphans
С версии:

6.4

Эти параметры включают предупреждение, если модуль содержит «сиротское» объявление экземпляра или правило переписывания. Объявление экземпляра считается сиротским, если оно находится в модуле, в котором не объявлены ни класс, ни инстанцируемый тип. Правило считается сиротским, если оно относится к функции, объявленной в другом модуле. Модуль, содержащий сиротские объявления, называется сиротским модулем.

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

Параметр -Worphans выдаёт предупреждение о пользовательских сиротских правилах или экземплярах.

-Woverlapping-patterns
С версии:

как минимум 5.04

По умолчанию компилятор предупреждает о перекрывающихся наборах образцов, например:

f :: String -> Int
f []     = 0
f (_:xs) = 1
f "2"    = 2

последняя ветвь сопоставления с образцом в f никогда не будет достигнута, поскольку второй образец перекрывает её. Избыточные образцы чаще всего являются ошибкой программиста, поэтому этот параметр включён по умолчанию.

Если программисту непременно нужно сохранить избыточную ветвь, например чтобы предотвратить постепенное ухудшение кода, можно использовать охранное выражение, проверяющее GHC.Exts.considerAccessible, чтобы средство проверки не считало родительскую ветвь избыточной:

g :: String -> Int
g []                       = 0
g (_:xs)                   = 1
g "2" | considerAccessible = 2 -- No warning!

Обратите внимание, что considerAccessible следует указывать последним выражением охранного выражения, чтобы не повлиять на результаты проверки. Например, если написать:

h :: Bool -> Int
h x = case (x, x) of
  (True,  True)  -> 1
  (False, False) -> 2
  (True,  False) | considerAccessible, False <- x -> 3

Средство проверки сопоставления с образцом воспримет это буквально, решит, что False <- x может завершиться неудачей, и предупредит о неполноте сопоставления с образцом. Чтобы избежать такой путаницы, поместите considerAccessible в конец.

Обратите внимание, что из-за технических ограничений considerAccessible не отключает предупреждения -Winaccessible-code.

-Winaccessible-code
С версии:

8.6

По умолчанию компилятор предупреждает, если типы делают ветвь недостижимой. Обычно для этого требуются GADT или подобные расширения.

Рассмотрим, например, следующую программу:

{-# LANGUAGE GADTs #-}

data Foo a where
 Foo1 :: Foo Char
 Foo2 :: Foo Int

data TyEquality a b where
        Refl :: TyEquality a a

checkTEQ :: Foo t -> Foo u -> Maybe (TyEquality t u)
checkTEQ x y = error "unimportant"

step2 :: Bool
step2 = case checkTEQ Foo1 Foo2 of
         Just Refl -> True -- Inaccessible code
         Nothing -> False

Ветвь Just Refl в step2 недостижима, поскольку для того, чтобы checkTEQ могло вернуть Just, должно выполняться t ~ u. Но поскольку здесь передаются Foo1 и Foo2, следует, что t ~ Char и u ~ Int, а значит, t ~ u не может выполняться.

-Wstar-is-type
С версии:

8.6

Использование * для обозначения рода обитаемых типов зависит от расширения StarIsType, которое в одном из будущих выпусков будет отключено по умолчанию и, возможно, затем удалено. Причины этого и график устаревания описаны в предложении GHC № 143.

Это предупреждение позволяет обнаружить такое использование * до внесения несовместимого изменения. Рекомендуемое исправление — заменить * на Type, импортированный из Data.Kind.

-Wstar-binder
С версии:

8.6

При включённом расширении StarIsType символ * в типах не является ни оператором, ни даже именем: это специальный синтаксис, обозначающий Data.Kind.Type. Это означает, что выражение вида Either * Char разбирается как Either (*) Char, а не как (*) Either Char.

Для позиций связывания действуют аналогичные правила разбора. Рассмотрим следующий пример:

{-# LANGUAGE TypeOperators, TypeFamilies, StarIsType #-}

type family a + b
type family a * b

Хотя a + b разбирается как (+) a b и становится позицией связывания для оператора типа (+), a * b разбирается как a (*) b и отклоняется.

В качестве обходного решения допускается связывать (*) в префиксной форме:

type family (*) a b

Такое решение довольно хрупкое, поскольку программист обычно ожидает, что (*) a b будет эквивалентно a * b. Параметр -Wstar-binder включает предупреждение о случаях, когда применяется эта специальная обработка (*).

-Wsimplifiable-class-constraints
С версии:

8.2

По умолчанию:

включено

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

f :: Eq [a] => a -> a

Здесь ограничение Eq [a] в сигнатуре пересекается с экземпляром верхнего уровня для Eq [a]. GHC прилагает определённые усилия, чтобы использовать первое, но если ему придётся использовать второе, возникнет неразрешимое ограничение Eq a. Лучше этого избежать, написав вместо этого:

f :: Eq a => a -> a
-Wtabs
С версии:

6.8

Включает предупреждение компилятора о символах табуляции в исходном файле.

-Wtype-defaults
С версии:

как минимум 5.04

По умолчанию:

выключено

Включает предупреждение или уведомление о том, где в исходном коде срабатывает механизм Haskell для выбора типа по умолчанию для числовых типов. Эта информация полезна при преобразовании кода из контекста, в котором предполагался один тип по умолчанию, в контекст с другим типом. Например, значение 1, тип которого иначе не был бы ограничен, согласно «значению по умолчанию по умолчанию» в Haskell 1.4 получало тип Int, тогда как в Haskell 98 и более поздних версиях его тип по умолчанию — Integer. Это может приводить к различиям в производительности и поведении, поэтому полезно получать соответствующие уведомления.

-Wmonomorphism-restriction
С версии:

6.8

По умолчанию:

выключено

Включает предупреждение или уведомление о том, где в исходном коде применяется ограничение мономорфизма Haskell. При незаметном применении ограничение мономорфизма может приводить к неожиданному поведению, поэтому полезно получать явное предупреждение о его применении.

-Wunsupported-llvm-version
С версии:

7.8

Выдаёт предупреждение при использовании -fllvm с неподдерживаемой версией LLVM.

-Wmissed-extra-shared-lib
С версии:

8.8

Выдаёт предупреждение, если GHCi не удаётся загрузить динамическую библиотеку, которую, согласно его выводам при загрузке пакета и анализе секции extra-libraries описания целевого пакета, следовало загрузить.

-Wunticked-promoted-constructors
С версии:

7.10

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

Например:

data Nat = Succ Nat | Zero

data Vec n s where
  Nil  :: Vec Zero a
  Cons :: a -> Vec n a -> Vec (Succ n) a

Будут выданы два предупреждения, поскольку Zero и Succ записаны не как 'Zero и 'Succ.

Начиная с версии 9.4 это также относится к литералам списков. Например:

type L = [Int, Char, Bool]

будет выдано предупреждение, поскольку [Int, Char, Bool] — это повышенный список без апострофа.

-Wunused-binds
С версии:

как минимум 5.04

Сообщает о неиспользуемых определениях функций и локальных связях. Это псевдоним для

  • -Wunused-top-binds
  • -Wunused-local-binds
  • -Wunused-pattern-binds
-Wunused-top-binds
С версии:

8.0

Сообщает о неиспользуемых определениях функций.

Точнее, выдаёт предупреждение, если связь вводит в область видимости неиспользуемую переменную, кроме случаев, когда её имя начинается с подчёркивания. Условие «имя начинается с подчёркивания» позволяет выборочно отключать предупреждение.

Переменная считается «используемой», если

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

Например:

module A (f) where
f = let (p,q) = rhs1 in t p  -- No warning: q is unused, but is locally bound
t = rhs3                     -- No warning: f is used, and hence so is t
g = h x                      -- Warning: g unused
h = rhs2                     -- Warning: h is only used in the
                             -- right-hand side of another unused binding
_w = True                    -- No warning: _w starts with an underscore
-Wunused-local-binds
С версии:

8.0

Сообщает о неиспользуемых локальных определениях. Например:

module A (f) where
f = let (p,q) = rhs1 in t p  -- Warning: q is unused
g = h x                      -- No warning: g is unused, but is a top-level binding
-Wunused-pattern-binds
С версии:

8.0

Выдаёт предупреждение, если связывание с образцом не связывает ни одной переменной, кроме случаев, когда образец состоит только из подстановочного знака или является строгим образцом. Например:

Just _ = rhs3    -- Warning: unused pattern binding
(_, _) = rhs4    -- Warning: unused pattern binding
_  = rhs3        -- No warning: lone wild-card pattern
!() = rhs4       -- No warning: banged pattern; behaves like seq

В общем случае ленивое связывание с образцом p = e ничего не делает, если p не связывает ни одной переменной. Подстановочные образцы без других элементов разрешены, поскольку они мало отличаются от _v = rhs3, которое не вызывает предупреждения; кроме того, они могут быть полезны для добавления ограничения типа, например _ = x::Int. Строгий образец (см. Строгие образцы и строгий Haskell) не является пустой операцией, поскольку он принудительно вычисляет значение и полезен как альтернатива seq.

-Wunused-imports
С версии:

как минимум 5.04

Сообщает о модулях, которые импортированы явно, но никогда не используются. При этом форма import M() никогда не считается неиспользуемым импортом, поскольку это полезный идиоматический способ импортировать объявления экземпляров, которые в Haskell являются анонимными.

-Wunused-matches
С версии:

как минимум 5.04

Сообщает обо всех неиспользуемых переменных, появляющихся при сопоставлении с образцом на уровне термов, в том числе об образцах, состоящих из одной переменной. Например, f x y = [] сообщит, что x и y не используются. Предупреждение не выдаётся, если имя переменной начинается с подчёркивания, например:

f _x = True

Обратите внимание, что параметр -Wunused-matches не выдаёт предупреждения о переменных, появляющихся в образцах на уровне типов, например в экземплярах семейства типов или семейства типов данных. Для этого нужно отдельно включить параметр -Wunused-type-patterns.

-Wunused-do-bind
С версии:

6.12

Сообщает о выражениях в блоках do и mdo, которые, судя по всему, незаметно отбрасывают данные. Например, do { mapM popInt xs ; return 10 } сообщит, что первое выражение в блоке do выглядит подозрительно: его тип — StackM [Int], а не StackM (), но это значение [Int] ни к чему не привязано. Предупреждение подавляется, если явно указать в исходном коде, что программа отбрасывает результат:

do { _ <- mapM popInt xs ; return 10 }

Разумеется, в этой конкретной ситуации можно поступить ещё лучше:

do { mapM_ popInt xs ; return 10 }
-Wunused-type-patterns
С версии:

8.0

Сообщает обо всех неиспользуемых неявно связаных переменных типа, которые возникают из шаблонов в экземплярах семейств типов и семейств данных. Например:

type instance F x y = []

сообщит, что x и y не используются в правой части. Предупреждение подавляется, если имя переменной типа начинается с символа подчёркивания, например:

type instance F _x _y = []

Если включено расширение ExplicitForAll, неиспользуемыми могут быть признаны и явно квантифицированные переменные типа. Например:

type instance forall x y. F x y = []

всё равно сообщит, что x и y не используются в правой части.

В отличие от -Wunused-matches, -Wunused-type-patterns не включается автоматически опцией -Wall. Причина в том, что в отличие от имён шаблонов на уровне термов, имена типов часто выбираются специально для документации, поэтому подчёркивания в именах типов могут затруднить её чтение.

-Wunused-foralls
С версии:

8.0

Сообщает обо всех неиспользуемых переменных типа, возникающих из явно записанных пользователем конструкций forall. Например:

g :: forall a b c. (b -> b)

сообщит, что a и c не используются.

-Wunused-record-wildcards
С версии:

8.10

Сообщает обо всех шаблонах-записях с подстановочными знаками, в которых не используется ни одна неявно связанная переменная. Например:

data P = P { x :: Int, y :: Int }

f1 :: P -> Int
f1 P{..} = 1 + 3

сообщит, что шаблон P{..} не используется.

-Wredundant-bang-patterns
С версии:

9.2

Сообщает о бесполезных шаблонах с восклицательным знаком: таких шаблонах, которые ни при каких обстоятельствах не могут вычислить thunk, который ещё не был вычислен. Бесполезные шаблоны с восклицательным знаком являются разновидностью избыточных шаблонов с восклицательным знаком. Эта проверка выполняется анализатором полноты сопоставления с шаблонами наряду с другими проверками (а именно, проверками избыточных и недоступных правых частей). Пусть дано:

f :: Bool -> Int
f True = 1
f !x   = 2

Шаблон с восклицательным знаком в !x бесполезен. К моменту достижения x во втором уравнении x уже будет вычислен первым уравнением (f True = 1). Кроме того, второе уравнение невозможно достичь, не пройдя через первое.

Обратите внимание, что -Wredundant-bang-patterns не сообщает о бесполезных шаблонах с восклицательным знаком, присутствующих в избыточной ветви. В таком случае рекомендуется полностью удалить ветвь, включая начальное сопоставление с шаблоном.

Бесполезные шаблоны с восклицательным знаком избыточны. Однако существуют избыточные шаблоны с восклицательным знаком, которые не являются бесполезными, например:

f !() = 0

восклицательный знак всё ещё вычисляет аргумент до попытки сопоставления с (). Но это избыточно, поскольку то же вычисление выполняется при сопоставлении с (). В настоящее время такие избыточные шаблоны не считаются бесполезными, и -Wredundant-bang-patterns о них не сообщает.

-Wredundant-record-wildcards
С версии:

8.10

Сообщает обо всех шаблонах-записях с подстановочными знаками, в которых сопоставление с подстановочным знаком не связывает ни одного шаблона. Например:

data P = P { x :: Int, y :: Int }

f1 :: P -> Int
f1 P{x,y,..} = x + y

сообщит, что в сопоставлении P{x, y, ..} избыточно используется ...

-Wredundant-strictness-flags
С версии:

9.4

Сообщает о флагах строгости, применённых к типам без указателя. Тип без указателя всегда строгий, поэтому применение флага строгости не влияет на него.

Например:

data T = T !Int#
-Wwrong-do-bind
С версии:

6.12

Сообщает о выражениях в блоках do и mdo, которым, судя по всему, не хватает связывания. Например, do { return (popInt 10) ; return 10 } сообщит, что первое выражение в блоке do выглядит подозрительно: оно имеет тип StackM (StackM Int) (состоящий из двух вложенных применений одного и того же конструктора монады), но его результат затем не «распаковывается» посредством связывания. Предупреждение подавляется, если явно указать в исходном коде, что программа отбрасывает результат:

do { _ <- return (popInt 10) ; return 10 }

Для почти всех разумных программ это указывает на ошибку, и, вероятно, вы хотели написать:

do { popInt 10 ; return 10 }
-Winline-rule-shadowing
С версии:

7.8

Предупреждает, если правило переписывания RULE может не сработать, потому что функция может быть встроена до того, как правило успеет сработать. См. раздел Взаимодействие правил с прагмами INLINE/NOINLINE.

-Wcpp-undef
С версии:

8.2

Этот флаг передаёт -Wundef препроцессору C (если он используется), чтобы тот предупреждал об использовании директивы #if с неопределёнными идентификаторами.

-Wunbanged-strict-patterns
С версии:

8.2

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

-Wmissing-home-modules
С версии:

8.2

Предупреждает, если импортирован модуль из компилируемого в данный момент пакета (то есть «домашнего» пакета), который явно не указан в командной строке в качестве цели. Полезно для Cabal, чтобы гарантировать, что GHC не подхватит модули, не перечисленные ни в exposed-modules, ни в other-modules.

-Wpartial-fields
С версии:

8.4

Опция -Wpartial-fields предупреждает о поле записи f, определённом в некоторых, но не во всех конструкторах типа данных, поскольку выбор и обновление записи в таком случае могут быть частичными. Например, если включена опция -Wpartial-fields, компилятор выдаст предупреждение при определении Foo ниже:

data Foo = Foo { f :: Int } | Bar

Предупреждение подавляется, если имя поля начинается с символа подчёркивания.

data Foo = Foo { _f :: Int } | Bar

Связанные предупреждения — -Wincomplete-record-selectors и -Wincomplete-record-updates; они сообщают об использовании, а не об определении.

-Wunused-packages
С версии:

8.10

Опция -Wunused-packages предупреждает о пакетах, указанных в командной строке с помощью -package ⟨pkg⟩ или -package-id ⟨unit-id⟩, но не потребовавшихся во время компиляции. Если предупреждение срабатывает, это означает, что указанный пакет не был нужен для компиляции.

Это предупреждение плохо взаимодействует с GHCi, поскольку при большинстве запусков при первоначальной загрузке передаётся большое количество аргументов -package. Поэтому при изменении целей с помощью :load или :cd предупреждение будет незаметно отключено, если оно включено (см. #21110).

-Winvalid-haddock
С версии:

9.0

Когда включена опция -haddock, GHC собирает комментарии документации и связывает их с объявлениями, аргументами функций, конструкторами данных и другими синтаксическими элементами. Комментарии документации в недопустимых позициях отбрасываются:

myValue =
  -- | Invalid (discarded) comment in an expression
  2 + 2

Это предупреждение сообщает об отброшенных комментариях документации. Оно не действует, если отключена опция -haddock.

-Woperator-whitespace-ext-conflict
С версии:

9.2

Если включено расширение TemplateHaskell, выражение f $x разбирается как f, применённое к нетипизированной вставке. Но если расширение отключено, выражение разбирается как использование инфиксного оператора $.

Чтобы выражение f $x было легко читать, не проверяя включённые расширения, его можно переписать как f $ x — именно это и предлагает данное предупреждение.

В настоящее время обнаруживаются следующие случаи:

  • $x может означать нетипизированную вставку при включённом расширении TemplateHaskell
  • $$x может означать типизированную вставку при включённом расширении TemplateHaskell
  • %m может означать аннотацию кратности при включённом расширении LinearTypes

Предупреждение охватывает только существующие в настоящее время расширения. Чтобы обеспечить более строгую политику и всегда требовать пробелы вокруг всех инфиксных операторов, используйте -Woperator-whitespace.

-Woperator-whitespace
С версии:

9.2

Согласно предложению GHC № 229, существует четыре типа вхождений инфиксных операторов:

a ! b   -- a loose infix occurrence
a!b     -- a tight infix occurrence
a !b    -- a prefix occurrence
a! b    -- a suffix occurrence

Свободное вхождение любого оператора всегда разбирается как инфиксный оператор, тогда как другим типам вхождений может придаваться специальное значение. Например, префиксный ! обозначает шаблон с восклицательным знаком, а префиксный $ — вставку TemplateHaskell.

Это предупреждение рекомендует использовать свободные вхождения для всех инфиксных операторов, чтобы избежать возможных конфликтов с будущими расширениями языка.

-Wauto-orphans
С версии:

7.4

Ничего не делает.

-Wmissing-space-after-bang
С версии:

8.8

Ничего не делает.

-Wderiving-typeable
С версии:

7.10

Этот флаг предупреждает, если Typeable указано в предложении deriving или выведено с помощью StandaloneDeriving.

Начиная с GHC 7.10, Typeable выводится автоматически для всех типов. Поэтому выводить Typeable самостоятельно избыточно.

-Wambiguous-fields
С версии:

9.2

Если включено расширение DuplicateRecordFields, опция -Wambiguous-fields предупреждает об использовании полей в селекторах или обновлениях, которое зависит от устаревшего механизма разрешения неоднозначности по типу. Этот механизм будет удалён в будущей версии GHC, после чего такие вхождения будут отклоняться как неоднозначные. Подробнее см. предложение DuplicateRecordFields без неоднозначного доступа к полям и документацию по расширению DuplicateRecordFields.

Это предупреждение не действует, если расширение DuplicateRecordFields отключено.

-Wforall-identifier
С версии:

9.4

Это предупреждение устарело. Начиная с GHC 9.10 оно больше не действует.

Раньше GHC допускал использование forall в качестве идентификатора на уровне термов:

-- from constraints-0.13
forall :: forall p. (forall a. Dict (p a)) -> Dict (Forall p)
forall d = ...

В соответствии с предложением GHC № 281, теперь это невозможно, поскольку forall стало полноценным ключевым словом. -Wforall-identifier использовался в переходный период до вступления в силу этого несовместимого изменения.

-Wunicode-bidirectional-format-characters
С версии:

9.0.2

Явные символы форматирования двунаправленного текста Unicode могут вводить в заблуждение при отображении исходного кода во многих программах просмотра. Предупреждение выдаётся, если в исходном коде присутствует хотя бы один такой символ.

В частности, предупреждение запрещает символы из категории «Explicit Formatting» в перечне типов двунаправленных символов Unicode.

-Wgadt-mono-local-binds
С версии:

9.4.1

Это предупреждение выдаётся при сопоставлении с шаблонами, включающем GADT, если отключено расширение MonoLocalBinds. В этом случае вывод типов может быть ненадёжным.

Подробнее см. статью OutsideIn(X) (раздел 4.2) и раздел Обобщение let.

Чтобы устранить это предупреждение, включите MonoLocalBinds или расширение, которое его подразумевает (GADTs либо TypeFamilies).

Предупреждение также выдаётся при сопоставлении с шаблонными синонимами, подобными GADT (то есть шаблонными синонимами, содержащими равенства в предоставляемых ограничениях).

В предыдущих версиях GHC (9.2 и ниже) сопоставление с шаблоном GADT считалось ошибкой, если не было включено ни GADTs, ни TypeFamilies.

-Wtype-equality-out-of-scope
С версии:

9.4.1

По умолчанию:

вкл.

В соответствии с предложением GHC № 371, синтаксис равенства типов a ~ b больше не является встроенным. Вместо этого ~ — обычный оператор типов, который можно импортировать из Data.Type.Equality или Prelude.

Чтобы свести к минимуму несовместимость, предусмотрен запасной вариант для совместимости: когда используется ~, но оно не находится в области видимости, компилятор считает, что оно обозначает ограничение равенства типов. Предупреждение выдаётся для любого кода, использующего этот запасной вариант. Его можно устранить, явно добавив ~ в область видимости.

Вероятнее всего, проблема связана с использованием NoImplicitPrelude и пользовательского Prelude. В этом случае обновите пользовательский Prelude, чтобы он повторно экспортировал ~ из Data.Type.Equality.

-Wtype-equality-requires-operators
С версии:

9.4.1

В соответствии с предложением GHC № 371, синтаксис равенства типов a ~ b больше не является встроенным. Вместо этого ~ — обычный оператор типов, для которого требуется расширение TypeOperators.

Чтобы свести к минимуму несовместимость, ~ (в отличие от других операторов типов) можно использовать, даже если расширение TypeOperators отключено. Предупреждение выдаётся при каждом таком использовании; его можно устранить, включив расширение.

-Wloopy-superclass-solve
С версии:

9.6.1

Это предупреждение устарело. Начиная с GHC 9.10 оно больше не действует. Раньше расширение UndecidableInstances допускало потенциально незавершающиеся свидетельства для некоторых ограничений суперклассов. Теперь это запрещено, как объясняется в разделе Неразрешимые экземпляры и циклические суперклассы. Это предупреждение использовалось в переходный период.

-Wterm-variable-capture
С версии:

9.8.1

При включённом расширении RequiredTypeArguments неявная квантификация переменных типа не выполняется, если в области видимости есть переменная-терм с тем же именем.

Например:

a = 15
f :: a -> a    -- NoRequiredTypeArguments: The ‘a’ is implicitly quantified
               -- RequiredTypeArguments:   The ‘a’ refers to the term-level binding

Если включено -Wterm-variable-capture, GHC предупреждает о неявной квантификации, которая перестала бы работать при включении RequiredTypeArguments.

-Wmissing-role-annotations
С версии:

9.8.1

По умолчанию:

выкл.

Чтобы GHC проверял наличие аннотации роли у каждого определения типа данных, используйте опцию -Wmissing-role-annotations. Роль можно указать с помощью расширения RoleAnnotations.

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

-Wimplicit-rhs-quantification
С версии:

9.8.1

По умолчанию:

вкл. (начиная с 9.14.1)

В соответствии с предложением GHC № 425, GHC прекратит неявно квантифицировать переменные типа, которые встречаются свободно в правой части синонима типа, но не упоминаются в левой части. Объявления синонимов типов, использующие такую форму квантификации, следует переписать с невидимыми связывателями.

Например:

type T1 :: forall a . Maybe a
type T1    = 'Nothing :: Maybe a      -- old
type T1 @a = 'Nothing :: Maybe a      -- new

Это предупреждение обнаруживает код, на который повлияет данное несовместимое изменение.

-Wincomplete-export-warnings
С версии:

9.8.1

В соответствии с предложением GHC № 134, теперь можно пометить как устаревшие отдельные экспорты имени, не помечая устаревшим само имя.

Как объясняется в разделе Прагмы WARNING и DEPRECATED, если имя экспортируется несколькими способами в одном модуле, но предупреждение указано лишь для некоторых из них, при импорте в другой модуль имя не будет считаться устаревшим.

Например:

module A (x) where

x :: Int
x = 2

module M (
    {-# WARNING x "deprecated" #-} x
    module A
  )
import A

Если включено -Wincomplete-export-warnings, GHC предупреждает об экспортах, не помечающих имя как устаревшее, если другой экспорт этого имени в том же модуле помечен как устаревший.

-Wbadly-levelled-types
С версии:

9.14.1

Рассмотрим пример:

tardy :: forall a. Proxy a -> IO Type
tardy _ = [t| a |]

Связывание типа a выполняется на уровне 0, но используется на уровне 1.

Это программа с неверно заданными уровнями, и tardy (Proxy @Int) создаст не представление типа для Int, а локальное имя a.

-Wbadly-staged-types
С версии:

9.10.1

Устаревший псевдоним для -Wbadly-levelled-types.

-Winconsistent-flags
С версии:

9.8.1

По умолчанию:

вкл.

Предупреждает о противоречиях между параметрами командной строки.

Например, при использовании GHCi флаги оптимизации игнорируются и выдаётся предупреждение. Другой пример: -dynamic игнорируется, если передан флаг -dynamic-too.

-Wdata-kinds-tc
С версии:

9.10.1

Это предупреждение устарело. Начиная с GHC 9.14 оно больше не действует.

Ранее GHC 9.10 и 9.12 были чрезмерно снисходительны к типам и видам, которые можно было использовать без включения расширения DataKinds. Однако в GHC 9.14 и более поздних версиях GHC теперь последовательно требует DataKinds, а все нарушения DataKinds теперь являются ошибками. -Wdata-kinds-tc использовался в период перехода до внесения несовместимого изменения.

-Wdefaulted-exception-context
С версии:

9.10.1

Добавлено в GHC 9.10.1 вместе с неявным контекстом Control.Exception.Context.ExceptionContext для Control.Exception.SomeException. Для сохранения совместимости с предыдущими компиляторами это ограничение неявно получает значение по умолчанию Control.Exception.Context.emptyExceptionContext, если нет других свидетельств. Поскольку такое поведение может привести к потере контекста исключения, это предупреждение сообщает о каждом случае присваивания значения по умолчанию.

-Wview-pattern-signatures
С версии:

9.12.1

Этот флаг добавлен в GHC 9.12.1 в соответствии с предложением GHC № 281. Он управляет предупреждением о непомещённых в скобки сигнатурах шаблонов в правой части шаблонов-представлений. Пример:

f (g -> p :: t) = ()

В будущей версии GHC этот код будет разбираться иначе:

f (g -> (p :: t)) = ()  -- current (legacy) parse
f ((g -> p) :: t) = ()  -- future parse

Если g не является эндофункцией (то есть её входной и выходной типы совпадают), это нарушит работу программы.

Чтобы обеспечить совместимость кода с будущими версиями и убрать предупреждение, рекомендуется вручную добавить скобки.

-Wunusable-unpack-pragmas
С версии:

9.14.1

По умолчанию:

включено

Предупреждать о неприменимых прагмах {-# UNPACK #-} в объявлениях типов данных. Примеры:

data T = MkT {-# UNPACK #-} !(Int -> Bool)

data G where
  MkG :: {-# UNPACK #-} !G -> G

type family F a where {}
data R a = MkR { fld :: {-# UNPACK #-} !(F a) }

Возможная причина этого предупреждения — применение прагмы {-# UNPACK #-} к одному из следующих элементов:

  • типу функции a -> b
  • рекурсивному использованию определяемого типа данных
  • типу-сумме, который нельзя распаковать
  • применению семейства типов или данных, для которого в окружении нет подходящего экземпляра

Однако предупреждение намеренно не выдаётся, если:

  • ошибка возникает в неопределённом пакете Backpack
  • прагму можно применить, но распаковка отключена с помощью -O0
-Wpattern-namespace-specifier
С версии:

9.14.1

По умолчанию:

выключено

Предупреждать об использовании устаревшего спецификатора пространства имён pattern в списках импорта и экспорта, например:

import Data.List.NonEmpty (pattern (:|))

Чтобы убрать предупреждение, используйте вместо него ключевое слово data:

import Data.List.NonEmpty (data (:|))

Если вы настроены на крайнюю осторожность, хорошим выбором будет параметр -dcore-lint. Он включает ресурсоёмкие проверки целостности между проходами компилятора GHC. (Проверяется корректность работы GHC, а не ваша.)

© 2002–2007 The University Court of the University of Glasgow. All rights reserved.
Licensed under the Glasgow Haskell Compiler License.
https://downloads.haskell.org/~ghc/9.14.1/docs/users_guide/using-warnings.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API