должен полностью описать, что вы можете с ним сделать. Если вы можете вызывать его только для определенных типов, это должно отражать сигнатура типа.

тоящее время я пытаюсь обернуть голову вокруг типов классов и экземпляров, и пока не совсем понимаю их смысл. У меня есть два вопроса по этому вопросу:

1) Почему необходимо иметь класс типа в сигнатуре функции, когда функция использует некоторую функцию из этого класса типов. Пример:

f :: (Eq a) => a -> a -> Bool
f a b = a == b

Зачем ставить(Eq a) в подписи. Если== не определено дляa тогда почему бы просто не скинуть ошибку при встречеa == b? Какой смысл в том, чтобы объявлять класс типа впереди?

2) Как связаны классы типов и перегрузка функций?

Это невозможно сделать:

data A = A
data B = B

f :: A -> A
f a = a

f :: B -> B
f b = b

Но это можно сделать так:

data A = A
data B = B

class F a where
  f :: a -> a

instance F A where
  f a = a

instance F B where
  f b = b

Что с этим? Почему у меня не может быть двух функций с одинаковым именем, но работающих на разных типах ... Исходя из C ++, я нахожу это очень странным. Но у меня, вероятно, неправильные представления о том, что это на самом деле. но как только я заверну их в эти экземпляры класса типов, я смогу.

Не стесняйтесь подбрасывать мне категории или вводить теоретические слова, так как я изучаю эти предметы параллельно с изучением Haskell, и я подозреваю, что в них есть теоретическая основа для того, как Haskell делает вещи здесь.

Ответы на вопрос(4)

Ваш ответ на вопрос