2015-06-15 2 views
0

Я пытаюсь реализовать функцию (Дерево a) -> (Дерево a) -> (Дерево a). Функция должна суммировать значения узлов и возвращать дерево с суммами. Unfortunatley я получил следующее сообщение об ошибке:Haskell неожиданный тип в объявлении класса

Aufgabe10.hs: 4: 11: Неожиданного типа «Дерево» В объявлении класса для «+» объявления класса должен иметь вид класса + а где .. .

Это мой код:

data Tree a = Node a (Tree a) (Tree a) 
    |Empty 

class (+) (Tree a) where 
    (+) :: (Tree a) (Tree a) -> (Tree a) 

instance (Num a) => (+) (Tree a) (Tree a) where 
    (+) (Node a1 b1 c1) (Node a2 b2 c2) = (Node (a1+a2) ((+) b1 b2) ((+) c1 c2)) 
    (+) Empty (Node a b c) = (Node a b c) 
    (+) (Node a b c) Empty = (Node a b c) 

Ok я изменил теперь класс для Plus и назвал функцию плюс, потому что я не хочу, чтобы реализовать все numb функции. Это новый код:

data Tree a = Node a (Tree a) (Tree a) 
    |Empty 

class Plus a where 
    plus:: (Tree a) -> (Tree a) -> (Tree a) 

instance (Num a) => Plus (Tree a) where 
    Plus (Node a1 b1 c1) (Node a2 b2 c2) = (Node (a1+a2) (Plus b1 b2) (Plus c1 c2)) 
    Plus Empty (Node a b c) = (Node a b c) 
    Plus (Node a b c) Empty = (Node a b c) 

я получаю следующие ошибки:

Aufgabe10.hs: 8: 9: Pattern привязок (за исключением простых переменных) не допускается в объявлениях экземпляра Plus (Node a1 b1 c1) (Node a2 b2 c2) = (Node (a1 + a2) (плюс b1 b2) (плюс c1 c2))

Aufgabe10.hs: 9: 9: Pattern привязок (за исключением простых переменных) не допускается в примерах объявления Плюс Пусто (Node abc) = (Узел abc)

Aufgabe10.hs: 10: 9: Pattern привязок (за исключением простых переменных) не допускается в декларациях экземпляра Plus (Node ABC) = Empty (Node ABC)

+4

Что вы пытаетесь достичь, написав 'class (+) (Tree a) where'? – Jubobs

+0

Мое понимание вашей домашней работы заключается в том, что вам нужно написать экземпляр 'Num' для' Tree a'. Вы, вероятно, не хотите писать объявление класса, здесь. Однако, если моя догадка верна, вам также придется реализовать другие методы, необходимые для объявления экземпляра 'Num'; см. http://hackage.haskell.org/package/base-4.8.0.0/docs/Prelude.html#g:7 – Jubobs

+1

'(Дерево a) (Дерево a) -> ...' также должно быть '(Дерево a) -> (Дерево a) -> ... ' – chi

ответ

2

Взгляните на What are typeclasses?: там ты будешь обратите внимание на то, что декларация типа товарных знаков принимает:

  1. название классного стекла;
  2. переменная типа.

Таким образом, ваше объявление должно начинаться

class (+) a where 

не

class (+) (Tree a) where 

хотя я бы предпочел

class Plus a where 

Это решает первую из ваших проблем. :)


Ответ на обновленную версию ...

Видите ли вы разницу между Plus и plus? Да, один капитализируется, а другой - нет. Знаете ли вы, что это значит в Haskell?

Plus, так как каждое капитализированное слово в Haskell, относится к типам (в данном случае, типа класс называется Plus).

С другой стороны, функции должны быть всегда строчными - и именно поэтому вы определили plus :: (Tree a) -> (Tree a) -> (Tree a) в нижнем регистре.

У вас уже есть проблема?

Вместо

instance (Num a) => Plus (Tree a) where 
    Plus (Node a1 b1 c1) (Node a2 b2 c2) = (Node (a1+a2) (Plus b1 b2) (Plus c1 c2)) 
    Plus Empty (Node a b c) = (Node a b c) 
    Plus (Node a b c) Empty = (Node a b c) 

вы должны иметь письменные

instance (Num a) => Plus (Tree a) where 
    plus (Node a1 b1 c1) (Node a2 b2 c2) = (Node (a1+a2) (Plus b1 b2) (Plus c1 c2)) 
    plus Empty (Node a b c) = (Node a b c) 
    plus (Node a b c) Empty = (Node a b c) 

потому, что вы определяете поведение функции plus когда Tree является экземпляром Plus. Понял? :)

Смежные вопросы