Как определить тип данных, состоящий из других типов данных? - PullRequest
2 голосов
/ 09 ноября 2019

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

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

data Euro = MkEuro Integer Integer
data Dollar = MkDollar Integer Integer
data Yen = MkYen Integer
data Currency = Euro | Dollar | Yen

Если я хочу использовать тип Валюта в любой функции, я получаю вариант следующего сообщения об ошибке:

Couldn't match expected type `Currency' with actual type `Dollar'

К сожалению, я должен использоватьвведите Валюта и не можете создавать разные функции для всех трех валют.

Ответы [ 2 ]

4 голосов
/ 09 ноября 2019

В настоящее время ваш Currency состоит из трех значений, которые принимают без параметров. Таким образом, Euro - это значение, Dollar - это значение, а Yen - это значение, но не MkYen 15.

. Вы можете добавлять параметры в свои конструкторы данных, например:

data Currency = Euro <b>Euro</b> | Dollar <b>Dollar</b> | Yen <b>Yen</b>

Тогда вы можете построить Currency с помощью:

<b>Euro</b> (MkEuro 14 25) :: Currency

:: Currency не необходим. Таким образом, MkEuro создаст объект типа Euro, а затем мы используем конструктор Euro data с типом Euro -> Currency для создания Currency.

К сожалению, я должен использовать тип Currency и не могу создавать разные функции для всех трех валют.

Возможно, вы захотите сделать Currency класс типов однако он предоставляет интерфейс, который сообщает, какие функции должна реализовывать валюта, а затем создает Euro, Dollar и Yen экземпляров этого класса типов.

2 голосов
/ 09 ноября 2019

Проблема с тем, что вы пытались сделать, заключается в том, что Euro, Dollar и Yen, определенные в первых 3 строках (слева от знаков =), являются типами , тогда как в последней строке справа указаны конструкторы данных . Это разные вещи, поэтому вам разрешено давать им одинаковые имена, но это также означает, что значение Dollar имеет тип Currency, а не типDollar.

У вас была правильная идея создать тип объединения, сочетающий остальные три, - но вы путаете конструкторы данных (которые являются просто «тегами») с типами значений, которые они содержат. Вы можете исправить это так:

data Currency = Euro Euro | Dollar Dollar | Yen Yen

Может показаться странным, что одно и то же имя встречается дважды (тоже трижды), но два вхождения имени имеют разные значения. Например, в Euro Euro первый Euro - это конструктор данных (функция, которая «маркирует» значение), а второй - тип , с которым работает функция конструктора.

...