Классы типов и типы данных
Насколько я понимаю, классы типов сами по себе не являются типами данных и, как таковые, не имеют реальных значений, связанных с ними.
Вот что я имею в виду. Класс типов всегда имеет хотя бы одну переменную типа. Когда вы пишете instance Num Int
, вы говорите, что если тип данных имеет ограничение Num a => a
, вы можете использовать Int
вместо a
.
Типы данных реализуют методы классов типов, а затем вы можете полиморфно использовать эти методы для любого из этих типов данных. +
- это метод для класса типов Num
. Int
и Double
имеют экземпляры Num
. Вот почему работают и 2 + 2
*, и 3.14 + 3.14
.
Итак, когда GH C сообщает вам, что он обнаружил переменную неоднозначного типа, это означает, что он знает набор типов данных, реализующих ограничение Graph a
, но он не знает, какой из них использовать. Чтобы вернуть его к Num
, если бы у вас было foo :: Num a => a
(предположим, что у него есть допустимое определение) и вы пытались выполнить foo + foo
, GH C не знал бы, использовать ли +
, определенный для Int
или Double
или любой другой тип данных, реализующий Num
.
Имея это в виду…
Ответ
Вы сможете решить свою проблему, выбрав Speci c экземпляр графика, например Tree
.
Технические характеристики
Во многих случаях, когда у вас есть переменная неоднозначного типа, вы можете подумать, что это не имеет значения, если GH C просто выбран какой-то тип данных, реализующий класс. Короче говоря, иногда бывает. GH C и GHCi реализуют выбор типа по умолчанию (см., Например, раздел 2.4.8 ), но делают это по-разному. GHCi в целом пытается использовать типы по умолчанию более агрессивно, чем GH C.
* Технически, когда вы пишете литерал вроде 2
, он не обязательно должен иметь тип Int
. Это технически относится к типу Num a => a
, а GH C пытается разрешить его тип во время вывода типа. Если он не решает проблему, по умолчанию используется его тип, как я полагаю, Integer
.