Пустой граф в библиотеке fgl - PullRequest
1 голос
/ 09 июля 2020

Я попытался создать пустой граф с String узлами и немаркированными ребрами следующим образом:

λ> let emptyGraph = empty :: Graph gr => gr String ()
λ> emptyGraph
emptyGraph :: Graph gr => gr String ()
λ> isEmpty emptyGraph
Ambiguous type variable ‘gr0’ arising from a use of ‘isEmpty’
      prevents the constraint ‘(Graph gr0)’ from being solved.

Я получаю ту же ошибку с isEmpty empty, правильно ли я указываю его тип?

Также, почему gr в сигнатуре типа является строчной буквой вместо ожидаемой заглавной буквы для имен типов данных?

Ссылка на библиотеку fgl

1 Ответ

1 голос
/ 09 июля 2020

Классы типов и типы данных

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

Вот что я имею в виду. Класс типов всегда имеет хотя бы одну переменную типа. Когда вы пишете 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...