Haskell unexpected type in class declaration

时间:2015-06-15 15:19:47

标签: class haskell

I try to implement a function (Tree a) -> (Tree a) -> (Tree a). The function should sum the node values and return a tree with the sums. Unfortunatley i got the following error message:

Aufgabe10.hs:4:11: Unexpected type ‘Tree a’ In the class declaration for ‘+’ A class declaration should have form class + a b c where ...

This is my code:

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 i changed now the class to Plus and named the function plus, cause i don't want to implement all the numb functions. This is the new code:

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)

I get the following errors:

Aufgabe10.hs:8:9: Pattern bindings (except simple variables) not allowed in instance declarations Plus (Node a1 b1 c1) (Node a2 b2 c2) = (Node (a1 + a2) (Plus b1 b2) (Plus c1 c2))

Aufgabe10.hs:9:9: Pattern bindings (except simple variables) not allowed in instance declarations Plus Empty (Node a b c) = (Node a b c)

Aufgabe10.hs:10:9: Pattern bindings (except simple variables) not allowed in instance declarations Plus (Node a b c) Empty = (Node a b c)

1 个答案:

答案 0 :(得分:2)

看看What are typeclasses?:你会注意到类型类声明需要:

  1. 类型名称;
  2. 一个类型变量。
  3. 因此,您的声明应该以

    开头
    class (+) a where
    

    class (+) (Tree a) where
    

    虽然我更喜欢

    class Plus a where
    

    这解决了你的第一个问题。 :)

    回答您的更新版本......

    您是否看到Plusplus之间的区别?是的,一个是资本化而另一个不是。你知道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)
    

    因为当plusTree的实例时,您正在定义函数Plus的行为。得到它了? :)