Как правильно создавать экземпляры классов в Haskell?

#haskell #typeclass

#haskell #класс типов

Вопрос:

Пытаюсь создать базовый класс, из которого я могу выводить разные типы. Что не так со следующим?

 class (Eq a) => MyClass a 

data Alpha = Alpha
instance MyClass Alpha where
    Alpha == Alpha = True
  

Я получаю сообщение об ошибке:

 test.hs:5:10: `==' is not a (visible) method of class `MyClass'
Failed, modules loaded: none.
  

Ответ №1:

Вы должны явно сделать Alpha экземпляром Eq. Это сработает:

 data Alpha = Alpha
instance Eq Alpha where
    Alpha == Alpha = True
instance MyClass Alpha
  

Комментарии:

1. Спасибо. Итак, если у меня есть строка наследования, я должен создавать экземпляры каждого из производных классов и не могу выполнить их все за один раз?

2. Правильно, но вы должны думать об этом скорее как «если a хочет создать экземпляр MyClass, ему сначала нужно создать экземпляр Eq», чем как о наследовании.

Ответ №2:

В первой строке говорится, что вам нужно сначала объявить Alpha экземпляром Eq, а затем MyClass.

Ответ №3:

Исходя из структуры вопроса, кажется, что вы ожидаете, что классы типов Haskell будут вести себя аналогично классам в объектно-ориентированном языке. Классы типов больше похожи на интерфейсы Java.

Наследования нет. Класс типов — это просто описание набора функций, которые реализованы для типа. В отличие от интерфейса Java, эти функции могут быть определены в терминах друг друга, так что для минимально полного объявления экземпляра может потребоваться только определение некоторых функций.