Я думаю, что есть несоответствие типов в определении по умолчанию в Примере 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)) в качестве типа своего первого аргумента. Следовательно, это и есть несоответствие типов, на которое Хаскелл должен жаловаться. Однако это принято как определение по умолчанию, и поэтому Хаскелл не жалуется на него там, где я думаю, что это должно быть.

Что я упускаю?

601   2  

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

    Ничего не найдено.