Собственный класс типов экземпляров Haskell

Мне нужно объявить свой собственный класс типов, но я не понимаю, почему существует (==).

data Egg = Soft | Hard

instance Eq Egg where
(==)

Я не нашел ничего, где (==) используется в экземпляре, только в классе


person Lorenzo    schedule 24.03.2017    source источник


Ответы (2)


Простой способ получить экземпляр Eq:

data Egg = Soft | Hard deriving Eq

Сложный способ (с большим контролем):

data Egg = Soft | Hard

instance Eq Egg where
  Soft == Soft = True
  Hard == Hard = True
  _    == _    = False

UPD: Поскольку функция равенства (==) в качестве оператора кажется немного запутанной, вот тот же пример, записанный с префиксной нотацией:

data Egg = Soft | Hard

instance Eq Egg where
  (==) Soft Soft = True
  (==) Hard Hard = True
  (==) _    _    = False

В качестве быстрого напоминания: по умолчанию операторы являются инфиксными (между терминами), а функции по умолчанию являются префиксными (перед терминами). Чтобы сделать префикс оператора, он окружен (), чтобы сделать инфикс функции, он окружен ``. Здесь рассказывается о том, какие символы используются для операторов и функций. .

person basile-henry    schedule 24.03.2017
comment
я тоже так думал, но они уже написали экземпляр Eq Egg, где (==) и мне нужно завершить код. (==) меня так смущает - person Lorenzo; 24.03.2017
comment
Вы запутались в операторе (==)? Я отредактирую свое решение, чтобы показать версию префикса - person basile-henry; 24.03.2017
comment
Я такой тупой, спасибо за ответ! Совсем забыл, что это префикс - person Lorenzo; 24.03.2017

Я предполагаю, что вы пытаетесь создать экземпляр стандартного класса типов Eq для своего пользовательского типа данных. Класс Eq определяется как:

class Eq a where

  (==) :: a -> a -> Bool
  a == b = not (a /= b)

  (/=) :: a -> a -> Bool
  a /= b = not (a == b)

То есть он определяет два метода == и /= (которые являются операторами) и обеспечивает реализацию каждого из них по умолчанию в терминах другого. Таким образом, чтобы создать экземпляр Eq для вашего собственного типа, вам необходимо обеспечить реализацию одной или обеих этих функций (== или /=) для вашего типа. Обратите внимание, что тело instance должно быть с отступом.

instance Eq Egg where
  Soft == Soft = True
  Hard == Hard = True
  _ == _ = False

Точно так же, как вы можете использовать оператор Haskell в форме префикса, заключив его в круглые скобки, например, (==) 1 1, вы также можете реализовать определение оператора в форме префикса:

instance Eq Egg where
  (==) Soft Soft = True
  (==) Hard Hard = True
  (==) _ _ = False

Вы даже можете использовать case, если хотите:

instance Eq Egg where
  (==) a b = case (a, b) of
    (Soft, Soft) -> True
    (Hard, Hard) -> True
    _ -> False

Обратите внимание, что все они аналогичны экземпляру, который будет автоматически сгенерирован для вас с помощью deriving:

data Egg = Soft | Hard
  deriving (Eq)
person Jon Purdy    schedule 24.03.2017