Примечание для других потенциальных участников: пожалуйста, не стесняйтесь использовать абстрактные или математические обозначения, чтобы высказать свою точку зрения. Если я нахожу ваш ответ неясным, я попрошу разъяснения, но в остальном не стесняйтесь выразить себя удобным способом.
Чтобы быть ясным: я не ищу "сейф" head
, и выбор head
, в частности, не имеет особого смысла. Суть вопроса следует за обсуждением head
и head'
, которые служат для обеспечения контекста.
Я работаю над Haskell уже несколько месяцев (вплоть до того, что он стал моим основным языком), но, правда, я не очень хорошо осведомлен о некоторых более продвинутых концепциях и деталях языка. философия (хотя я более чем готов учиться). Тогда мой вопрос не столько технический (если это не так, а я просто не понимаю), но и философский.
Для этого примера я говорю о head
.
Как я понимаю, вы узнаете,
Prelude> head []
*** Exception: Prelude.head: empty list
Это следует из head :: [a] -> a
. Справедливо. Очевидно, что никто не может вернуть элемент (махнув рукой) никакого типа. Но в то же время просто (если не тривиально) определить
head' :: [a] -> Maybe a
head' [] = Nothing
head' (x:xs) = Just x
Я видел небольшое обсуждение этого здесь в разделе комментариев некоторых утверждений. Примечательно, что один Алекс Штангл говорит
'Есть веские причины не делать все "безопасным" и не создавать исключений при нарушении предварительных условий.'
Я не обязательно ставлю под сомнение это утверждение, но мне любопытно, каковы эти "веские причины".
Кроме того, Пол Джонсон говорит,
'Например, вы можете определить «safeHead :: [a] -> Возможно a», но теперь вместо того, чтобы обрабатывать пустой список или доказывать, что это не может произойти, вы должны обработать «Nothing» или доказать, что оно может не бывает.
Тон, который я прочитал из этого комментария, говорит о том, что это заметное увеличение сложности / сложности / чего-то, но я не уверен, что понимаю, что он там излагает.
Один Стивен Прузина говорит (в 2011 году, не меньше),
"Существует более глубокая причина, почему, например, 'head' не может быть защищенным от сбоев. Чтобы быть полиморфным, но обрабатывать пустой список, 'head' всегда должен возвращать переменную типа, который отсутствует в каком-либо конкретном пустом списке. Было бы Delphic, если бы Haskell мог сделать это ... ".
Полиморфизм потерян, если разрешить обработку пустого списка? Если так, то как и почему? Есть ли конкретные случаи, которые сделали бы это очевидным? В этом разделе подробно ответил @Russell O'Connor. Любые дальнейшие мысли, конечно, приветствуются.
Я отредактирую это в соответствии с требованиями ясности и предложения. Любые мысли, документы и т. Д., Которые вы можете предоставить, будут наиболее ценными.