Классы Eq Ord Данные Haskell

Теперь у меня другая проблема:

Другая подзадача говорит мне вывести тип данных из классов.

Я не знаю, как это сравнить. У вас есть идея, и не могли бы вы объяснить ее мне, чтобы я мог понять?

``

Экземпляр Eq, где ...

Пример или где ...

Непонятно, как вы планируете сравнивать доллары с йенами. Должна ли ваша программа получать обменные курсы из Интернета или что-то в этом роде?

n. m. 20.11.2022 19:59

Ваше редактирование делает вопрос едва значимым и, безусловно, отделяет его от уже данных ответов.

chepner 21.11.2022 17:27
[JS за 1 час] - 9. Асинхронный
[JS за 1 час] - 9. Асинхронный
JavaScript является однопоточным, то есть он может обрабатывать только одну задачу за раз. Для обработки длительных задач, таких как сетевые запросы,...
Топ-10 компаний-разработчиков PHP
Топ-10 компаний-разработчиков PHP
Если вы ищете надежных разработчиков PHP рядом с вами, вот список лучших компаний по разработке PHP.
Скраппинг поиска Apple App Store с помощью Python
Скраппинг поиска Apple App Store с помощью Python
📌Примечание: В этой статье я покажу вам, как скрапировать поиск Apple App Store и получить точно такой же результат, как на Apple iMac, потому что...
Редкие достижения на Github ✨
Редкие достижения на Github ✨
Редкая коллекция доступна в профиле на GitHub ✨
Подъем в javascript
Подъем в javascript
Hoisting - это поведение в JavaScript, при котором переменные и объявления функций автоматически "перемещаются" в верхнюю часть соответствующих...
Улучшение генерации файлов Angular
Улучшение генерации файлов Angular
Angular - это фреймворк. Вы можете создать практически любое приложение без использования сторонних библиотек.
1
2
148
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

eqCurrency :: Currency -> Currency -> Bool
eqCurrency ...

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

eqCurrency :: Currency -> Currency -> Bool
eqCurrency (Dollar d1 c1) (Dollar d2 c2) = ... 
eqCurrency (Yen y1) (Yen y2) = ...
eqCurrency (Euro d1 c1) (Euro d2 c2) = ...

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

eqCurrency _c1 _c2 = False

Как только вы написали эту функцию и довольны ее поведением, вы можете вставить ее в класс типа:

instance Eq Currency where
  (==) = eqCurrency

Вам нужно будет сделать то же самое для класса типа Ord. Для Ord, минимальное полное определение является либо определяющим <=, либо compare, поэтому вам следует выбрать одно из них. Например, вы можете определить:

leqCurrency :: Currency -> Currency -> Bool
leqCurrency ...

Вы снова зададите себе те же вопросы: если у меня есть две суммы Dollar, когда одна меньше другой? Если у меня есть Euro и Yen, какая из них меньше другой? Я не могу ответить вам на эти семантические вопросы, но вы будете использовать свои ответы для кодирования различных случаев, и когда вы закончите, вы сможете заполнить класс типа:

instance Ord Currency where
  (<=) = leqCurrency

Я думаю, у вас опечатка - в последнем блоке кода Eq должно быть Ord

Quelklef 20.11.2022 20:45

Да, спасибо, что поймали!

DDub 20.11.2022 23:22
Я не знаю, как сравнить каждую валюту

И я нет. «Как следует сравнивать валюты» — это скорее вопрос дизайна, чем реализации.

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

Похоже, это упражнение, так что, может быть, было бы справедливо выбрать фиксированные обменные курсы для вашей программы? Google сообщает мне, что на момент написания один цент США стоит 1,4 иены, поэтому я согласен с этим.

Тогда мы знаем один случай для ord:

instance Ord Currency where
  compare (Dollar dollars cents) (Yen yen) = compare ((dollars*100 + cents) * 1.4) yen
  -- ...

Остальная часть экземпляра Ord может быть заполнена аналогичным образом, с вариантами для compare (Yen ...) (Dollar ...) и compare (Dollar ...) (Euro ...) и т. д. и т. д.

Эта реализация будет работать, и ее стоит заполнить полностью.

Однако есть «более чистое» решение, если вам интересно. Мы можем выбрать какую-нибудь «якорную» валюту, скажем, йену. Затем мы можем написать так называемую функцию «нормализации», которая конвертирует каждую валюту в иену:

normalize :: Currency -> Integer
normalize (Dollar dollars cents) = (dollars*100 + cents) * 1.4
-- you fill in the rest

Используя это, мы можем написать Ord проще, как просто

instance Ord Currency where
  compare c1 c2 = compare (normalize c1) (normalize c2)

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