Вот определение Maybe
типа:
data Maybe a = Nothing | Just a
Это указывает, что для некоторых типов a
, тип Maybe a
имеет два конструктора: Nothing
и Just a
(a
быть такой же тип переменной, которая Maybe
применяется к на LHS).
Надеюсь, это ясно, как Just "foo"
имеет тип Maybe String
и Just 'c'
имеет тип Maybe Char
. Но какой тип Nothing
? Поскольку Nothing
не содержит никакого значения, его конструктор не использует переменную типа a
, и поэтому нет ничего, что ограничивало бы его тип определенной формой Maybe
.
Это делает его «полиморфной константой». Nothing
может использоваться в контексте, в котором ожидается любой тип Maybe
, поскольку он одинаково хорошо работает во всех них. Вот почему GHCi сообщает свой тип как просто Maybe a
: a
- это переменная, которая может представлять любой тип, и какой тип, к которому он относится, будет определяться путем вывода на основе контекста, в котором используется значение Nothing
. Но когда вы даете Nothing
сами по себе, дополнительных указаний относительно его конкретного типа нет, поэтому вы просто видите переменную.
> :t Nothing
Nothing :: Maybe a
> :t (Nothing :: Maybe Int)
(Nothing :: Maybe Int) :: Maybe Int
> :t (Nothing :: Maybe Char)
(Nothing :: Maybe Char) :: Maybe Char
И, кстати, Just Nothing :: Maybe (Maybe a)
; это Maybe
, завернутый в другой Maybe
.
И так как я помню, что это не тонуло сразу, когда я только начинал: заглавное имя ('Maybe') слева от' = '* встречается только в сигнатурах типов *, тогда как имена для право '=' есть * найдено только в коде *. По соглашению и потому, что значение никогда не может быть двусмысленным, для типов с одним конструктором, часто конструктор типа будет иметь то же имя, что и его тип. Я думаю, что это путает op. – jberryman