Haskell - class vs typeclass - what's the difference

Hi, Haskellers and Haskellettes,

I played with Haskell for quite some time, but there is such a concept of classes that I cannot understand. In the following example, I have an ExprTree data ExprTree

 data Val a = Num a | Var String deriving (Eq, Ord, Show) data ExprTree = Leaf {lab::Label, val::(Val a)=> a} | Node {lab::Label, fun::Fun, lBranch::ExprTree, rBranch::ExprTree} deriving(Eq,Ord) 

that leads to

 Type constructor `Val' used as a class In the definition of data constructor `Leaf' In the data type declaration for `ExprTree' 

I also tried

 data ExprTree' = Leaf {lab::Label, val::Val} ... 

but a random change in type signature is neither sound nor effective nor enlightening.

now, as far as I know, Num a denotes something from the Num class, but it is not an instance of a data type - and does not allow me to compile. So what I need to do to make ExprTree correct.

Thanks in advance for the tips and ideas!


Edit

1) Thanks for the quick answers!

2) I changed val::(Val a)=>a to val::Val a

I had something similar, but then an error occurs: Not in scope type variable a do you have any additional tips?

+6
source share
5 answers

The correct type will be

 data Val a = Num a | Var String deriving (Eq, Ord, Show) data ExprTree a = Leaf {lab::Label, val :: Val a} | Node {lab::Label, fun::Fun, lBranch::ExprTree a, rBranch::ExprTree a} deriving(Eq,Ord) 

Since the Val type requires an additional type parameter, you must specify it every time you use it * . I used a type variable, as in the initial definition; which requires the variable to also be called the ExprTree parameter. (Other possibilities are to use a specific type, such as Int or Maybe String , etc., or to use an existential type, and it makes no sense here.)

What you actually used is the typeclass context ("class" is just an abbreviation for "typeclass"). Val is a type, not a type, so it is not legal.

* This is not entirely true; you need a type type * . Types - types of types: Int has the form * , Val a has the form * , Val has the form * -> * . That is, Val itself is a type function that requires a parameter to become complete.

+3
source

To answer the question in the headline: When it comes to Haskell, the word "class" is almost always used to mean "typeclass", because it is the only class in the class that exists in Haskell. Therefore there is no difference.

To answer a question in your body:

 data ExprTree a = Leaf {lab::Label, val::(Val a)} | Node {lab::Label, fun::Fun, lBranch::(ExprTree a), rBranch::(ExprTree a)} deriving(Eq,Ord) 

Writing (Val a)=>a makes no sense, because Val not a style class, and you cannot just enter typeclass type restrictions on the right side of the type definition (without extensions in any case), and in any case it’s not that , What would you like).

+5
source

The error points to this part of the type definition:

 val::(Val a)=> a 

This syntax means that "for any instance of a for typeclass Val value Val is of type a ." But then (1) Val not a class, and (2) type a seems to come out of the air.

What did you possibly intend to say

 data Val a = Num a | Var String deriving (Eq, Ord, Show) data ExprTree a = Leaf { val :: Val a } | Node { lBranch :: ExprTree a, rBranch :: ExprTree a } deriving (Eq, Ord) 
+2
source

Your problem has already been resolved, but I see that you are using GHC, and sometimes - especially at the beginning - Hugs error messages can be read a little easier, in this case:

Syntax error in data type declaration (unexpected `=> ')

This could give you the first idea of ​​where to look. Keep in mind that I am not protecting Hugs over GHC here, but as a Haskell novice, I think the former provides more useful error messages.

+1
source

If you use OOP, a few simple rules can help you navigate:

  • When Haskellers talk about classes or classes, it vaguely looks like an interface or trait in OOP.
  • What appears on LHS data ... = ... is vaguely like an abstract superclass. You cannot do this, but you can declare a parameter of this type.
  • What appears in the RHS data ... = ... is vaguely similar to specific subclasses.
  • If you need the parameter to be a class of type that is on LHS =>, as in Num t => t.

Now none of this is strictly correct, and if you stay here, but a rough idea helped me get my foundation.

0
source

Source: https://habr.com/ru/post/891656/


All Articles