Как Haskell узнает, какой экземпляр класса типов вы имеете в виду?

StackOverflow https://stackoverflow.com/questions/817466

Вопрос

Этот вопрос возник при чтении новой главы в превосходном Learn You a Haskell о аппликативных функторах.

Аппликативный класс типов имеет, как часть определения для экземпляра Maybe:

pure = Just

Если я просто пойду в GHCi и импортирую Control.Applicative, и сделаю:

pure (3+)

Я ничего не понимаю (имеет смысл). Но если я использую это в части выражения:

pure (3+) <*> Just 4

Я получаю Just 7. Думаю, это тоже не удивительно, но мне не хватает чего-то интегрального в том, как работают классы типов, я думаю, что здесь нет двусмысленности при вызове pure здесь.

Если мое замешательство имеет смысл, кто-нибудь может объяснить, что происходит в деталях?

Это было полезно?

Решение

Это просто вывод типа. Оператор (<*>) требует, чтобы оба аргумента использовали один и тот же экземпляр Applicative. Правая сторона - это Maybe, поэтому левая сторона тоже должна быть :t expression. Так вот как он выясняет, какой экземпляр используется здесь. Вы можете посмотреть на тип любого выражения в интерпретаторе, набрав <=>, и, возможно, если вы просто просмотрите каждое подвыражение и посмотрите на тип, который был выведен, вы получите более полное представление о том, что происходит.

Другие советы

Стоит посмотреть на тип, который компилятор выводит для pure (3+):

Prelude Control.Applicative> :t pure (3+)
pure (3+) :: (Num a, Applicative f) => f (a -> a)

Тип этого термина перегружен, и решение о числовом классе и аппликативном классе откладывается на потом. Но вы можете вызвать конкретный тип с помощью аннотации, например:

*Showfun Control.Applicative> pure (3+) :: Maybe (Double -> Double)
Just <function>

(Это работает, потому что Showfun имеет объявление экземпляра, которое печатает значение функции как <function>.)

Вопрос лишь в том, когда компилятор накопил достаточно информации, чтобы принять решение.

Чтобы немного расширить ответ newacct, если для вывода фактического типа недостаточно информации, компилятор может (в некоторых случаях) попытаться выбрать тип по умолчанию, ограниченный теми, которые удовлетворяют рассматриваемым ограничениям типов , В этом случае предполагаемый тип - IO (n - & Gt; n) для некоторого трудно определяемого экземпляра Num = & Gt; п. Затем GHCi оценивает его и выбрасывает возвращаемое значение без видимого эффекта.

Вот интересный SO поток при выводе типа . Не специфично для Haskell, но есть много хороших ссылок и материалов для чтения о выводе типов на функциональных языках.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top