Подтвердить что ты не робот

Следует ли указывать подпись типа для основного или нет? Почему, почему нет?

Я узнал из глава 9 "Узнайте, что вы Haskell For Great Good",

По соглашению мы обычно не указываем объявление типа для main.

Насколько я могу судить, эта конвенция широко распространена. Однако, если я скомпилирую, используя флаг -Wall, программу, которая не имеет сигнатуры типа для main, например

-- test.hs

-- main :: IO ()
main = print (1 :: Int)

GHC выдает предупреждение:

$ ghc -Wall test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )

test.hs:2:1: Warning:
    Top-level binding with no type signature: main :: IO ()
Linking test ...
$

Я запутался... Если сигнатура типа для main действительно лишняя, почему -Wall заставляет GHC жаловаться, когда она отсутствует? Есть ли веские причины (кроме устранения этого предупреждения) для указания типа main?

4b9b3361

Ответ 1

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

По соглашению мы указываем объявление типа для всего 1.

Разумеется, в большом проекте main сам по себе делает небрежное усилие, поэтому действительно не имеет смысла опускать подпись. Просто напишите, ради последовательности.

Однако, хотя Haskell отлично подходит для правильно структурированных проектов и на самом деле существует тенденция писать почти все в библиотеках, это также удивительно хорошо, как быстрый язык сценариев, для других, которые люди пишут на Python или Perl. И в этих случаях вам, как правило, не важно, что касается безопасности и хорошей документации и т.д., Вы просто хотите быстро записать что-то как можно более сжатое, что делает работу. Обычно вы не компилируете эти сценарии с помощью -Wall, а просто выполняете их с помощью runhaskell. И поскольку скрипты всегда должны содержать main (в отличие от большинства других исходных файлов Haskell), действительно достаточно разумно опустить здесь подпись.

Я все еще подозреваю, что большинство Haskellers в настоящее время пишут main::IO() даже в самых простых сценариях, если только по привычке.


1 Только все на верхнем уровне. Локальные подписи иногда также имеют смысл, но часто они скорее загромождают код.

Ответ 2

На самом деле очень хорошая идея написать сигнатуру типа для main, так как в противном случае, если вы слишком задумываетесь о том, чтобы писать вещи в беспутной форме, вы можете получить main типа IO (IO ()). Это принято (стандарт языка говорит, что main должен иметь какой-то тип формы IO a), но "внутреннее действие IO", являющееся результатом main, будет просто отброшено, что почти наверняка не является тем вы хотели (вы, вероятно, хотели join его).