7.2. Предупреждения и проверка на корректность
GHC имеет ряд опций, которые выбирают типы сообщений об ошибках, не приводящих к сбою, иначе известных как предупреждения, которые могут генерироваться во время компиляции. Некоторые опции управляют отдельными предупреждениями, а другие — группами предупреждений. Чтобы отключить отдельное предупреждение -W<wflag>, используйте -Wno-<wflag>. Чтобы отменить -Werror, что превращает все предупреждения в ошибки, используйте -Wwarn.
По умолчанию вы получаете стандартный набор предупреждений, которые, как правило, указывают на ошибки в вашей программе. Это:
Следующие флаги являются простыми способами выбора стандартных «пакетов» предупреждений:
-
-W -
Предоставляет стандартные предупреждения плюс
-
-Wall -
Включает все параметры предупреждений, которые указывают на потенциально подозрительный код. Предупреждения, которые не включены параметром
-Wall, следующие:
-
-Weverything -
Включает каждое отдельное предупреждение, поддерживаемое компилятором.
-
-Wcompat -
Включает предупреждения, которые будут включены по умолчанию в будущем, но остаются отключенными при обычных компиляциях. Это позволяет авторам библиотек, стремящимся к будущей совместимости, адаптироваться к новым функциям, прежде чем они будут генерировать предупреждения.
В настоящее время это включает
-
-Wno-compat -
Отключает все предупреждения, включенные параметром
-Wcompat.
-
-w -
Отключает все предупреждения, включая стандартные и те, которые
-Wallне включает.
Эти опции управляют тем, какие предупреждения считаются фатальными и приводят к прерыванию компиляции.
-
-Werror -
Превращает любое предупреждение в фатальную ошибку. Полезно, чтобы не пропускать предупреждения при пакетной компиляции. Чтобы отменить
-Werrorи прекратить обработку предупреждений как ошибок, используйте-Wwarn, или используйте-Wwarn=<wflag>для прекращения обработки определенных предупреждений как ошибок.
-
-Werror=⟨wflag⟩ -
- Подразумевает
-
-W<wflag>
Превращает конкретное предупреждение в фатальную ошибку. Предупреждение будет включено, если оно еще не включено. Можно отменить с помощью
-Wwarn=<wflag>.-Werror=compatимеет тот же эффект, что и-Werror=...для каждого флага предупреждения в группе опций-Wcompat.
-
-Wwarn -
Предупреждения обрабатываются только как предупреждения, а не как ошибки. Это значение по умолчанию, но может быть полезно для отмены флага
-Werror.
-
-Wwarn=⟨wflag⟩ -
Приводит к тому, что конкретное предупреждение обрабатывается как обычное предупреждение, а не как фатальная ошибка.
Обратите внимание, что это не полностью отменяет действие
-Werror=<wflag>- предупреждение все равно будет включено.-Wwarn=compatимеет тот же эффект, что и-Wwarn=...для каждого флага предупреждения в группе опций-Wcompat.
Когда выводится предупреждение, отображается конкретный флаг предупреждения, который его контролирует.
-
-fshow-warning-groups -
При отображении флага, контролирующего предупреждение, также отображаются соответствующие флаги группы предупреждений, к которой относится предупреждение.
Этот параметр выключен по умолчанию.
Полный набор опций предупреждений описан ниже. Чтобы отключить любое предупреждение, просто укажите соответствующий -Wno-... параметр в командной строке. Для обеспечения обратной совместимости с версиями GHC до 8.0 все эти предупреждения все еще можно контролировать с помощью -f(no-)warn-* вместо -W(no-)*.
-
-Wunrecognised-warning-flags -
- Значение по умолчанию
-
включено
Включает предупреждения, когда компилятор сталкивается с флагом
-W..., который не распознается.
-
-Wcompat-unqualified-imports -
Предупреждает при импорте модулей ядра библиотеки без указания квалификатора, которые могут измениться в будущих версиях GHC. В настоящее время предупреждение распространяется на следующие модули:
-
Data.Listиз-за будущего добавленияData.List.singletonи специализации экспортов в тип[]. Подробности см. на списке рассылки.
Это предупреждение можно устранить, добавив явный список импортов или используя
qualifiedимпорт. -
-
-Wtyped-holes -
- По умолчанию
-
включено
Определяет, будут ли компилятором выводиться предупреждения о типовых дырах. Не имеет эффекта, если ошибки типовых дыр не отложены до выполнения. См. Типовые дыры и Отложение ошибок типов до выполнения
-
-Wdeferred-type-errors -
Вызывает вывод предупреждения при откладывании ошибки типа до выполнения. См. Отложение ошибок типов до выполнения
Это предупреждение включено по умолчанию.
-
-fdefer-type-errors -
- Подразумевает
Откладывает как можно больше ошибок типов до выполнения. Во время компиляции вы получаете предупреждение (вместо ошибки). При выполнении, если вы используете значение, зависящее от ошибки типа, вы получите ошибку выполнения; но вы можете без проблем выполнить любые части кода, корректные с точки зрения типов. См. Отложение ошибок типов до выполнения
-
-fdefer-typed-holes -
Откладывает ошибки типовых дыр (ошибки о именах с ведущим символом подчёркивания (например, «_», «_foo», «_bar»)) до выполнения. Это превратит ошибки, создаваемые типовыми дырами в предупреждения. Использование значения, зависящего от типовой дыры, приводит к ошибке выполнения, так же как и
-fdefer-type-errors(который подразумевает этот параметр). См. Типовые дыры и Отложение ошибок типов до выполнения.Подразумевается
-fdefer-type-errors. Также см.-Wtyped-holes.
-
-fdefer-out-of-scope-variables -
Отложить ошибки переменных, выходящих за пределы области видимости, до выполнения. Это превратит ошибки переменных, выходящих за пределы области видимости, в предупреждения. Использование значения, зависящего от переменной, выходящей за пределы области видимости, приводит к ошибке выполнения, аналогично
-fdefer-type-errors(который подразумевает этот параметр). См. Типовые дыры и Отложение ошибок типов до выполнения.Подразумевается
-fdefer-type-errors. Также см.-Wdeferred-out-of-scope-variables.
-
-Wdeferred-out-of-scope-variables -
Предупреждает при обнаружении отложенной переменной, выходящей за пределы области видимости.
-
-Wpartial-type-signatures -
Определяет, будет ли компилятор сообщать о дырах в частичных сигнатурах типов в виде предупреждений. Не имеет эффекта, если не включена
PartialTypeSignatures, которая управляет тем, должны ли генерироваться ошибки для дыр в типах или нет. См. Частичные сигнатуры типов.Это предупреждение включено по умолчанию.
-
-fhelpful-errors -
При отсутствии имени или пакета в области видимости предлагать возможные варианты имени или пакета.
Этот параметр включен по умолчанию.
-
-Wunrecognised-pragmas -
Выводит предупреждение при использовании директивы (pragma), которую GHC не распознает. Помимо директив, используемых самим GHC, GHC также распознает директивы, используемые другими инструментами, например,
OPTIONS_HUGSиDERIVE.Этот параметр включен по умолчанию.
-
-Wmissed-specialisations -
Выводит предупреждение, если GHC не может специализировать перегруженную функцию, обычно потому, что функции требуется директива
INLINABLE. Сообщает об этом при специализации импортированной функции.Этот формат предназначен для выявления случаев, когда импортированная функция, помеченная как
INLINABLE(предположительно для включения специализации), не может быть специализирована, так как она вызывает другие функции, которые сами не специализированы.Обратите внимание, что это предупреждение не вызовет ошибок при использовании с
-Werror.Этот параметр выключен по умолчанию.
-
-Wall-missed-specialisations -
Выводит предупреждение, если GHC не может специализировать перегруженную функцию, обычно потому, что функции требуется директива
INLINABLE. Сообщает обо всех таких ситуациях.Обратите внимание, что это предупреждение не вызовет ошибок при использовании с
-Werror.Этот параметр выключен по умолчанию.
-
-Wwarnings-deprecations -
Выводит предупреждение при использовании модуля, функции или типа с директивой
WARNINGилиDEPRECATED pragma. См. Директивы WARNING и DEPRECATED для получения дополнительной информации о директивах.Этот параметр включен по умолчанию.
-
-Wdeprecations -
Выводит предупреждение при использовании модуля, функции или типа с директивой
WARNINGилиDEPRECATED pragma. См. Директивы WARNING и DEPRECATED для получения дополнительной информации о директивах. Псевдоним для-Wwarnings-deprecations.Этот параметр включен по умолчанию.
-
-Wnoncanonical-monad-instances -
Предупреждает при обнаружении неканонических
ApplicativeилиMonadобъявлений экземпляров.При включенном предупреждении проверяются следующие условия:
В
Monadобъявлениях экземпляров предупреждение выводится, если не выполняются следующие условия:- Если
returnопределено, оно должно быть каноническим (т.е.return = pure). - Если
(>>)определено, оно должно быть каноническим (т.е.(>>) = (*>)).
Кроме того, в
Applicativeобъявлениях экземпляров:- Предупреждение выводится, если
pureопределено в обратном порядке (т.е.pure = return). - Предупреждение выводится, если
(*>)определено в обратном порядке (т.е.(*>) = (>>)).
Этот параметр выключен по умолчанию.
- Если
-
-Wnoncanonical-monadfail-instances -
Предупреждает при обнаружении неканонических
MonadилиMonadFailобъявлений экземпляров.При включенном предупреждении проверяются следующие условия:
В
Monadобъявлениях экземпляров предупреждение выводится, если не выполняется следующее условие:- Если
failопределено, оно должно быть каноническим (т.е.fail = Control.Monad.Fail.fail).
Кроме того, в
MonadFailобъявлениях экземпляров:- Предупреждение выводится, если
failопределено в обратном порядке (т.е.fail = Control.Monad.fail).
См. также
-Wmissing-monadfail-instances.Этот параметр выключен по умолчанию.
- Если
-
-Wnoncanonical-monoid-instances -
Предупреждает при обнаружении неканонических
SemigroupилиMonoidобъявлений экземпляров.При включенном предупреждении проверяются следующие условия:
В
Monoidобъявлениях экземпляров предупреждение выводится, если не выполняется следующее условие:- Если
mappendопределено, оно должно быть каноническим (т.е.mappend = (Data.Semigroup.<>)).
Кроме того, в
Semigroupобъявлениях экземпляров:- Предупреждение выводится, если
(<>)определено в обратном порядке (т.е.(<>) = mappend).
Это предупреждение выключено по умолчанию. Однако оно входит в группу параметров
-Wcompat. - Если
-
-Wmissing-monadfail-instances -
Выводить предупреждение, когда в блоке do используется неуправляемый шаблон, у которого нет экземпляра
MonadFail.См. также
-Wnoncanonical-monadfail-instances.Поскольку эта опция входит в группу
-Wcompat, по умолчанию она отключена, но будет включена в будущих релизах GHC как часть предложения MonadFail (MFP).
-
-Wsemigroup -
Выдавать предупреждение, когда определения конфликтуют с будущим включением
Semigroupв стандартные типеклассы.- Экземпляры
Monoidдолжны также быть экземплярамиSemigroup - Оператор
Semigroup(<>)будет вPrelude, что сталкивается с пользовательскими локальными определениями такого оператора.
Поскольку эта опция входит в группу
-Wcompat, по умолчанию она отключена, но будет включена в будущих релизах GHC. - Экземпляры
-
-Wdeprecated-flags -
Вызывает предупреждение при использовании устаревшего флага командной строки.
Этот флаг включен по умолчанию.
-
-Wunsupported-calling-conventions -
Вызывает предупреждение для внешних объявлений, использующих неподдерживаемые соглашения о вызове. В частности, если используется соглашение о вызове
stdcallна архитектуре, отличной от i386, оно будет обрабатываться какccall.
-
-Wdodgy-foreign-imports -
Вызывает предупреждение для внешних импортов следующего вида:
foreign import "f" f :: FunPtr t
с обоснованием, что, вероятно, должно быть
foreign import "&f" f :: FunPtr t
Первый вариант объявляет, что
fявляется (чистой) C-функцией, которая не принимает аргументов и возвращает указатель на C-функцию с типомt, в то время как второй вариант объявляет, чтоfсам по себе является C-функцией с типомt. Первый вариант, как правило, является ошибкой, и ее трудно отладить, поскольку она приводит к сбою, отсюда и это предупреждение.
-
-Wdodgy-exports -
Вызывает предупреждение, когда тип данных
Tэкспортируется со всеми конструкторами, т. е.T(..), но это просто синоним типа.Также вызывает предупреждение при повторном экспорте модуля, если этот модуль ничего не экспортирует.
-
-Wdodgy-imports -
Вызывает предупреждение в следующих случаях:
- Когда тип данных
Tимпортируется со всеми конструкторами, т. е.T(..), но экспортируется абстрактно, т. е.T. - Когда оператор
importскрывает сущность, которая не экспортируется.
- Когда тип данных
-
-Woverflowed-literals -
Вызывает предупреждение, если литерал переполнится, например,
300 :: Word8.
-
-Wempty-enumerations -
Вызывает предупреждение, если перечисление пустое, например,
[5 .. 3].
-
-Wderiving-defaults -
- Since
-
8.10
Вызывает предупреждение, когда оба
DeriveAnyClassиGeneralizedNewtypeDerivingвключены, и никакая явная стратегия вывода не используется. Например, это приведет к предупреждению:class C a newtype T a = MkT a deriving C
-
-Wduplicate-constraints -
Вызывать предупреждение компилятора о дублирующих ограничениях в сигнатуре типа. Например
f :: (Eq a, Show a, Eq a) => a -> a
Предупреждение укажет на дублирующее ограничение
Eq a.Эта опция теперь устарела и заменена на
-Wredundant-constraints.
-
-Wredundant-constraints -
- Since
-
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 -
Вызывать предупреждение компилятора о дублирующихся записях в списках экспорта. Это полезная информация, если вы поддерживаете большие списки экспорта и хотите избежать непрерывного экспорта определения после удаления (одного) упоминания о нем в списке экспорта.
Этот флаг включен по умолчанию.
-
-Whi-shadowing -
Вызывает предупреждение компилятора, когда модуль или интерфейсный файл в текущем каталоге затеняет файл с тем же именем модуля в библиотеке или другом каталоге.
Этот флаг не был реализован правильно и теперь устарел. Он будет удален в более поздней версии GHC.
-
-Widentities -
Вызывает предупреждение компилятора, когда преобразование чисел Prelude преобразует тип
Tв тот же типT; такие вызовы, вероятно, являются операциями «ничего не делается», и их можно опустить. Проверяемые функции:toInteger,toRational,fromIntegral, иrealToFrac.
-
-Wimplicit-kind-vars -
Вызывает предупреждение компилятора, если переменная типа не явно квантифицируется. Например, следующее вызовет предупреждение:
f :: forall (a :: k). Proxy a
Это можно исправить, явно квантифицировав
k:f :: forall k (a :: k). Proxy a
-
-Wimplicit-prelude -
Вызывает предупреждение компилятора, если Prelude импортируется неявно. Это происходит, если модуль Prelude не импортируется явно с помощью строки
import ... Prelude ..., или этот неявный импорт отключен (либо с помощьюNoImplicitPrelude, либо с помощьюLANGUAGE NoImplicitPreludeпсевдонима).Обратите внимание, что предупреждение не выдается для синтаксиса, неявно ссылающегося на Prelude, даже если
NoImplicitPreludeизменило бы ссылку на Prelude. Например, предупреждение не выдается, когда368означаетPrelude.fromInteger (368::Prelude.Integer)(гдеPreludeотносится к фактическому модулю Prelude, независимо от импорта компилируемого модуля).Это предупреждение отключено по умолчанию.
-
-Wincomplete-patterns -
Опция
-Wincomplete-patternsпредупреждает о местах, где сопоставление с образцом может завершиться неудачей во время выполнения. Функцияgниже потерпит неудачу при применении к непустым спискам, поэтому компилятор выведет предупреждение об этом при включенном-Wincomplete-patterns.g [] = 2
Эта опция не включена по умолчанию, так как может быть несколько шумной и не всегда указывает на ошибку в программе. Однако, как правило, рекомендуется охватывать все случаи в ваших функциях, и она включена по умолчанию с
-W.
-
-Wincomplete-uni-patterns -
Флаг
-Wincomplete-uni-patternsаналогичен-Wincomplete-patterns, за исключением того, что он применяется только к лямбда-выражениям и связям с образцами, конструкциям, допускающим только один шаблон:h = \[] -> 2 Just k = f y
-
-fmax-pmcheck-models=⟨n⟩ -
- По умолчанию
-
100
Проверка соответствия шаблонов работает, присваивая символические значения каждому шаблону. Мы называем каждое такое присваивание «моделью». Теперь каждый пункт соответствия шаблону может привести к потенциальному множеству разделений этой модели, кодирующих различные способы, которыми может произойти несовпадение шаблона. Например, при сопоставлении
xсJust 4, мы разбиваем каждую входящую модель соответствия на две подмодели, в которых не соблюдается соответствие: одну, гдеxявляетсяNothing, и одну, гдеxявляетсяJust y, ноyне является4.В некоторых случаях это может быть экспоненциально от арности шаблона и от количества условий в нем. Ограничение
-fmax-pmcheck-models=⟨n⟩гарантирует, что мы масштабируемся полиномиально от количества шаблонов, забывая усовершенствованную информацию, полученную от частично успешного соответствия. Для приведенного выше примера, если у нас было бы ограничение в 1, мы бы продолжили проверку следующего пункта с оригинальной, не уточненной моделью.
-
-Wincomplete-record-updates -
Функция
fниже не будет работать при применении кBar, поэтому компилятор выведет предупреждение об этом, когда включен-Wincomplete-record-updates.data Foo = Foo { x :: Int } | Bar f :: Foo -> Foo f foo = foo { x = 6 }Этот параметр не включен по умолчанию, потому что он может быть очень шумным, и часто не указывает на ошибку в программе.
-
-Wmissing-deriving-strategies -
- С
-
8.8.1
Тип данных ниже наследует
Eqтипе класс, но не указывает стратегию. Когда-Wmissing-deriving-strategiesвключено, компилятор выведет предупреждение об этом.data Foo a = Foo a deriving (Eq)
Компилятор выведет здесь предупреждение о том, что в пункте наследования не указана стратегия. Если предупреждение включено, но
DerivingStrategiesне включено, компилятор предложит включить расширениеDerivingStrategies. Этот параметр по умолчанию отключен, и его нужно включать вручную или с помощью-Weverything.
-
-Wmissing-fields -
Этот параметр включен по умолчанию и выводит предупреждение всякий раз, когда построение констуктора помеченного поля не завершено, что означает отсутствие инициализаторов для одного или нескольких полей. Хотя это не ошибка (отсутствующие поля инициализируются с использованием значений по умолчанию), это часто указывает на ошибку программиста.
-
-Wmissing-export-lists -
- С
-
8.4.1
Этот флаг выводит предупреждение, если вы объявляете модуль без явного списка экспорта. Например
module M where p x = x
Флаг
-Wmissing-export-listsвыведет предупреждение, чтоMне объявляет список экспорта. Объявление явного списка экспорта дляMпозволяет GHC анализировать «мертвый код» в модуле, предотвращает случайный экспорт имен и облегчает оптимизации, например, встраивание.
-
-Wmissing-import-lists -
Этот флаг выводит предупреждение, если вы используете неопределенное
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 -
Этот параметр включён по умолчанию и выводит предупреждение всякий раз, когда объявление экземпляра отсутствует один или несколько методов, а соответствующее объявление класса не имеет для них дефолтного объявления.
Предикат
MINIMALможет использоваться для изменения набора методов, необходимых для экземпляров данного класса. См. MINIMAL предикат.
-
-Wmissing-signatures -
Если вы хотите, чтобы GHC проверял, что у каждой функции/значения верхнего уровня есть сигнатура типа, используйте параметр
-Wmissing-signatures. В рамках предупреждения GHC также сообщает выведенный тип. Параметр по умолчанию выключен.
-
-Wmissing-exported-sigs -
Этот параметр теперь устарел и заменен на
-Wmissing-exported-signatures.
-
-Wmissing-exported-signatures -
Если вы хотите, чтобы GHC проверял, что у каждой экспортированной функции/значения верхнего уровня есть сигнатура типа, но не проверял неэкспортированные значения, используйте параметр
-Wmissing-exported-signatures. Этот параметр имеет приоритет над-Wmissing-signatures. В рамках предупреждения GHC также сообщает выведенный тип. Параметр по умолчанию выключен.
-
-Wmissing-local-sigs -
Этот параметр теперь устарел и заменен на
-Wmissing-local-signatures.
-
-Wmissing-local-signatures -
Если вы используете флаг
-Wmissing-local-signatures, GHC выведет предупреждение о любых полиморфных локальных связываниях. В рамках предупреждения GHC также сообщает выведенный тип. Параметр по умолчанию выключен.
-
-Wmissing-pattern-synonym-signatures -
Если вы хотите, чтобы GHC проверял, что у каждого псевдонима шаблона есть сигнатура типа, используйте параметр
-Wmissing-pattern-synonym-signatures. Если этот параметр используется совместно с-Wmissing-exported-signatures, то у экспортированных псевдонимов шаблонов должна быть сигнатура типа. GHC также сообщает выведенный тип. Параметр по умолчанию выключен.
-
-Wname-shadowing -
Этот параметр вызывает выведение предупреждения всякий раз, когда значение во внутренней области видимости имеет то же имя, что и значение во внешней области видимости, т. е. внутреннее значение скрывает внешнее. Это может обнаруживать опечатки, которые превращаются в трудно обнаруживаемые ошибки, например, при непроизвольном использовании рекурсивного вызова в
f = ... let f = id in ... f ....Предупреждение подавляется для имён, начинающихся с нижнего подчеркивания. Например
f x = do { _ignore <- this; _ignore <- that; return (the other) }
-
-Worphans -
Эти флаги вызывают выведение предупреждения всякий раз, когда модуль содержит объявление «сиротского» экземпляра или правило переписывания. Объявление экземпляра является сиротой, если оно появляется в модуле, в котором ни класс, ни тип, подлежащие инстанциированию, не объявлены в том же модуле. Правило является сиротой, если это правило для функции, объявленной в другом модуле. Модуль, содержащий любые сиротские объявления, называется сиротским модулем.
Проблема с сиротами заключается в том, что GHC должен проактивно читать файлы интерфейса всех сиротских модулей, на случай, если их экземпляры или правила играют роль, независимо от того, будет ли интерфейс модуля в противном случае полезен. См. Сиротские модули и объявления экземпляров для получения подробной информации.
Флаг
-Worphansпредупреждает о сиротских правилах или экземплярах, написанных пользователем.
-
-Woverlapping-patterns -
По умолчанию компилятор выведет предупреждение, если набор шаблонов перекрывается, например:
f :: String -> Int f [] = 0 f (_:xs) = 1 f "2" = 2
где последний пункт соответствия шаблона в
fникогда не будет достигнут, так как второй шаблон перекрывает его. Чаще всего избыточные шаблоны являются ошибкой программиста, поэтому этот параметр включён по умолчанию.
-
-Winaccessible-code -
По умолчанию компилятор выведет предупреждение, если типы сделают ветвь недоступной. Это обычно требует расширений GADTs или аналогичных.
Например, рассмотрим следующую программу
{-# 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 -
- Since
-
8.6
Использование
*для обозначения типа обитаемых типов зависит от расширенияStarIsType, которое в будущей версии будет по умолчанию выключено, а затем, возможно, удалено. Причины этого и график устаревания описаны в предложении GHC №30.Это предупреждение позволяет обнаружить такие использования
*до фактического изменения, которое внесет разрыв в обратной совместимости. Рекомендуемое исправление — заменить*наTypeизData.Kind.Как часть группы опций
-Wcompat, это предупреждение по умолчанию выключено, но будет включено в будущей версии GHC.
-
-Wstar-binder -
В соответствии с
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 -
- Since
-
8.2
Предупреждение о ограничениях класса в сигнатуре типа, которые могут быть упрощены с помощью объявления экземпляра верхнего уровня. Например:
f :: Eq [a] => a -> a
Здесь
Eq [a]в сигнатуре перекрывается с экземпляром верхнего уровня дляEq [a]. GHC прилагает усилия для использования первого, но если он должен использовать последний, у него возникнет неразрешимоеEq aограничение. Лучше этого избежать, написав вместо этого:f :: Eq a => a -> a
Этот параметр включен по умолчанию. Как обычно, вы можете отключить его для каждого модуля с
-Wno-simplifiable-class-constraints.
-
-Wspace-after-bang
-
-Wtabs -
Компилятор выведет предупреждение, если в исходном файле есть символы табуляции.
-
-Wtype-defaults -
Компилятор предупредит/сообщит вам, где в вашем исходном коде срабатывает механизм Haskell по умолчанию для числовых типов. Это полезная информация при преобразовании кода из контекста, предполагавшего один параметр по умолчанию, в контекст с другим, например, «default default» для Haskell 1.4 приводило к тому, что значение
1имело типInt, в то время как Haskell 98 и более поздние версии по умолчанию устанавливают типInteger. Это может привести к различиям в производительности и поведении, поэтому полезно получать об этом информацию.Это предупреждение выключено по умолчанию.
-
-Wmonomorphism-restriction -
Компилятор предупредит/сообщит вам, где в вашем исходном коде применяется ограничение мономорфизма Haskell. Если ограничение применяется без предупреждения, это может привести к неожиданному поведению, поэтому полезно получать явное предупреждение о его применении.
Это предупреждение выключено по умолчанию.
-
-Wunsupported-llvm-version -
Предупреждение при использовании
-fllvmс неподдерживаемой версией LLVM.
-
Предупреждение, когда GHCi не может загрузить общую библиотеку, которую он вычислил, что должен загрузить при загрузке пакета и анализе раздела extra-libraries описания целевого пакета.
-
-Wunticked-promoted-constructors -
Предупреждение, если продвинутый конструктор данных используется без тильды перед его именем.
Например:
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.Это предупреждение включено по умолчанию в режиме
-Wall.
-
-Wunused-binds -
Сообщает об определениях функций (и локальных связей), которые не используются. Синоним для
-
-Wunused-top-binds -
Сообщает об определениях функций, которые не используются.
Точнее, предупреждает, если связывание вводит в область видимости переменную, которая не используется, за исключением случаев, когда имя переменной начинается с символа подчеркивания. Условие «начинается с символа подчеркивания» позволяет выборочно отключать предупреждение.
Переменная считается «используемой», если
- Она экспортирована, или
- Она появляется в правой части связывания, которое связывает по крайней мере одну используемую переменную, которая используется
Например:
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 -
Сообщает о локальных определениях, которые не используются. Например:
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 -
Предупреждает, если связывание по шаблону не связывает никаких переменных вообще, если это не единственный шаблон подстановки или шаблон с «!» (bang). Например:
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. Шаблон с «!» (bang) (см. Шаблоны bang и строго типизированный Haskell) — это не бесполезное действие, потому что он принуждает к вычислению и полезен как альтернативаseq.
-
-Wunused-imports -
Сообщает о модулях, которые явно импортированы, но никогда не используются. Однако форма
import M()никогда не сообщается как неиспользуемый импорт, потому что это полезный прием для импорта объявлений экземпляров, которые являются анонимными в Haskell.
-
-Wunused-matches -
Сообщает обо всех неиспользуемых переменных, которые возникают из сопоставления шаблонов на уровне терминов, включая шаблоны, состоящие из одной переменной. Например,
f x y = []сообщит оxиyкак о неиспользуемых. Предупреждение подавляется, если имя переменной начинается с символа подчеркивания, например:f _x = True
Обратите внимание, что
-Wunused-matchesне предупреждает о переменных, которые возникают из шаблонов на уровне типов, как в экземплярах типов семейств и семейств данных. Это необходимо включить отдельно через флаг-Wunused-type-patterns.
-
-Wunused-do-bind -
Сообщает об выражениях, встречающихся в
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 -
Сообщает обо всех неиспользуемых неявно связанных переменных типа, которые возникают из шаблонов в экземплярах семейств типов и семейств данных. Например:
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 -
Сообщает обо всех неиспользуемых переменных типов, которые возникают из явных, написанных пользователем
forallутверждений. Например:g :: forall a b c. (b -> b)
будет сообщать о
aиcкак неиспользуемых.
-
-Wunused-record-wildcards -
- Since
-
8.10.1
Сообщает обо всех диких картах записей, где ни одна из переменных, неявно связанных, не используется. Например:
data P = P { x :: Int, y :: Int } f1 :: P -> Int f1 P{..} = 1 + 3будет сообщать о том, что
P{..}соответствие не используется.
-
-Wredundant-record-wildcards -
- Since
-
8.10.1
Сообщает обо всех диких картах записей, где сопоставление диких карт не связывает никаких шаблонов. Например:
data P = P { x :: Int, y :: Int } f1 :: P -> Int f1 P{x,y,..} = x + yбудет сообщать о том, что
P{x, y, ..}сопоставление имеет избыточное использование...
-
-Wwrong-do-bind -
Сообщает об выражениях, встречающихся в
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 -
Выдаёт предупреждение, если переопределение RULE может не сработать, потому что функция может быть встроена до того, как правило будет иметь шанс сработать. Смотрите Как правила взаимодействуют с директивами INLINE/NOINLINE.
-
-Wcpp-undef -
- Since
-
8.2
Этот флаг передаёт
-Wundefв препроцессор C (если он используется), что заставляет препроцессор предупреждать об использовании директивы#ifна неопределённых идентификаторах.
-
-Wunbanged-strict-patterns -
Этот флаг предупреждает всякий раз, когда вы пишете шаблон, который связывает переменную, тип которой не поднят, и тем не менее шаблон не является ни шаблоном bang, ни голой переменной. Смотрите Неподнятые типы для получения информации о неподнятых типах.
-
-Wmissing-home-modules -
- Since
-
8.2
Когда модуль, предоставленный пакетом, который в данный момент компилируется (т.е. «домашний» пакет), импортируется, но не указан явно в командной строке в качестве целевого модуля. Полезно для Cabal, чтобы убедиться, что GHC не загрузит модули, не указанные ни в
exposed-modules, ни вother-modules.
-
-Wpartial-fields -
- Since
-
8.4
Опция
-Wpartial-fieldsпредупреждает о полях записей, которые могут потерпеть неудачу при обращении к ним через отсутствующий конструктор. Функцияfниже потерпит неудачу при применении кBar, поэтому компилятор выведет предупреждение при её определении, когда включена-Wpartial-fields.Предупреждение подавляется, если имя поля начинается с подчёркивания.
data Foo = Foo { f :: Int } | Bar
-
-Wunused-packages -
- Since
-
8.10
Опция
-Wunused-packagesпредупреждает о пакетах, указанных в командной строке через-package ⟨pkg⟩или-package-id ⟨unit-id⟩, но которые не были загружены во время компиляции. Обычно это означает, что у вас есть неиспользуемая зависимость.Вы можете включить это предупреждение при чистой сборке или включить
-fforce-recompдля получения надёжных результатов.
Если вы чувствуете себя действительно параноиком, -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/8.10.2/docs/html/users_guide/using-warnings.html