Ключевая проблема позволяет любому значению, чтобы быть null
(далее «миллиард долларов ошибки») является то, что интерфейсы, принимающие значения типа T
не имеют возможностей заявить, могут ли они справиться с null
и интерфейсами, что никто не может заявить, могут ли они произвести null
. Это означает, что все операций, которые можно использовать на T
, по существу, «может не работать», когда вы передаете им T
, что является довольно зияющим отверстием во всех гарантиях, предположительно предоставляемых методами проверки типа компиляции.
Может быть/Дополнительным решение это сказать, что тип T
не содержит значения null
(на языках, которые имели это с самого начала, это буквальное, в языках внедряющих дополнительный типа позже, не снимая поддержку null
, тогда это только конвенция, требующая дисциплины). Итак, теперь все операции, тип которых говорит, что они принимают T
, должны работать, когда я передаю им T
, независимо от того, где я получил T
(если вам не удалось создать «сделать незаконные состояния непредставимыми», тогда будет конечно, другие причины, по которым объект может находиться в недопустимом состоянии и вызывать сбой, но, по крайней мере, когда вы передаете T
, на самом деле будет что-то).
Иногда нам нужно значение, которое может быть «либо T
, либо ничего». Это такой обычный случай, который повсеместно выглядел как хорошая идея в то время. Введите тип Maybe T
. Но чтобы не возвращаться в точно такую же старую ловушку, где я получаю значение нулевого значения T
и передаю его чему-то, что не может обрабатывать null
, нам необходимо, чтобы ни одна из операций на T
не может использоваться непосредственно на Maybe T
. Получение типа ошибки от попыток сделать это - вся суть упражнения. Поэтому мои значения T
не могут быть непосредственно членами Maybe T
; Мне нужно, чтобы обернуть их внутриMaybe T
, так что если у меня есть Maybe T
я вынужден написать код, который обрабатывает как случаев (и только в том случае, для фактически имея T
можно назвать операции, которые работают на T
).
ли это делает слово как Just
или Some
появляется в исходном коде, и будет ли это на самом деле реализовано с дополнительным боксом/косвенностью в памяти (некоторые языки представляют собой Maybe T
как обнуляемый указатель T
внутренне), все это не имеет значения. Но случай Just a
должен быть отличным от простого значения a
.
'данные Может быть a = a | Ничего недействительно Haskell - он не будет компилироваться. Это определение эффективно подразумевало бы «Может быть,» является * объединением * любого значения или «Ничего», но это довольно бесполезно, так как «Ничто» также «любое значение». (Система типа Haskell не поддерживает такие неразделенные союзы, как это вообще, поскольку для этого потребуется некоторое понятие «подтипирование», которое у Haskell не имеет.) –
Нет, 'Maybe a' будет объединением' a' или ' Nothing', а 'Nothing' обычно не будет значением типа' a', поэтому такой тип, как 'Maybe Int', не будет бесполезным. Исправьте, что Haskell этого не поддерживает. –