Я думаю, что есть несоответствие типов в определении по умолчанию в Примере Applicative, возможно, в Haskell
В настоящее время я изучаю Хаскелла с профессором Хаттоном "программирование в Хаскелле", и я обнаружил кое-что странное относительно определения возможно как экземпляра класса Applicative.
В GHC.Base экземпляр Applicative Maybe определяется следующим образом:
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
Меня беспокоит строка, которая определяет значение
Nothing <*> _ как Nothing. Nothing имеет тип Maybe a, где оператор <*> фактически требует f (a -> b) (в данном случае Maybe (a -> b)) в качестве типа своего первого аргумента. Следовательно, это и есть несоответствие типов, на которое Хаскелл должен жаловаться. Однако это принято как определение по умолчанию, и поэтому Хаскелл не жалуется на него там, где я думаю, что это должно быть.Что я упускаю?
2 ответов:
(Это точно так же, как если бы вы написали
aвMaybe aявляется переменной типа и может быть любым типом вообще! Так чтоNothingможет иметь типMaybe Int, илиMaybe [x], илиMaybe (p -> q), например. Пусть вас не смущает тот факт, что имя переменнойaиспользуется в двух местах.aв типеNothing- это совершенно другая переменная, чемaв типе<*>, и просто случайно имеет то же самое имя!f x = x + 5, а затем в другом месте,g x = "Hello, " ++ x. Использованиеxв обоих местах не имеет значения, потому что они находятся в разных областях. То же самое сaв этом типе. Различные области,поэтому они являются различными переменными.)
Давайте проясним ситуацию, переназначив переменную типа:
Nothing :: Maybe xТип
Maybe xобъединяется сMaybe (a -> b), сx ~ (a -> b). То естьNothing- это значение, которое может использоваться какMaybe aдля любогоa, включая тип функции. Таким образом, это законный аргумент левой руки для<*>здесь.
Comments