Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - class vs typeclass - what is the difference

Hello Haskellers and Haskellettes,

I've been fiddling around with Haskell for quite a while but there is this concept of classes I cannot quite grasp. In the following example I have the datatype of 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)

which 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 randomly changing type signature - neither sounds efficent nor provides enlightenment.

now as far as i know Num a denotes something of class Num but is this is no instance of a datatype - and doesn't let me compile. So what do i have to do in order to make ExprTree well defined.

Thanks in advance for hints and ideas!


Edit:

1) Thanks for the fast answers!

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

i had something similar in mind - but then the error: Not in scope type variable a occurs do you have additional advice ??

like image 639
epsilonhalbe Avatar asked Jun 29 '11 16:06

epsilonhalbe


People also ask

What is a Typeclass in Haskell?

What's a typeclass in Haskell? A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.

Is type and classes the same?

The class defines object's internal state and the implementation of its operations. In contrast, an object's type only refers to its interface - a set of requests to which it can respond. An object can have many types, and objects of different classes can have the same type.

How are Typeclasses different from interfaces?

An interface in the Java programming language is an abstract type that is used to specify an interface (in the generic sense of the term) that classes must implement. These two looks rather similar: type class limit a type's behavior, while interface limit a class' behavior.

Does Haskell have different types?

Everything in Haskell has a type, so the compiler can reason quite a lot about your program before compiling it. Unlike Java or Pascal, Haskell has type inference.


4 Answers

To answer the question in the title: When talking about Haskell, the word "class" is almost always used to mean "typeclass" as that's the only kind of class there is in Haskell. So there is no difference.

To answer the 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 isn't a typeclass and you can't just introduce typeclass constraints on the right hand side of a type definition (without extensions anyway - and either way it's not what you want).

like image 75
sepp2k Avatar answered Oct 11 '22 15:10

sepp2k


The correct type would 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 type Val requires an additional type parameter, you need to provide one whenever you use it*. I used a type variable, just as in the initial definition; that requires the variable to also be named as a parameter to ExprTree. (The other possibilities would be to use a concrete type such as Int or Maybe String, etc., or to use an existential type; neither makes sense here.)

What you actually used was a typeclass context ("class" is just shorthand for "typeclass"). Val is a type, not a typeclass, so it's not legal there.

* This isn't quite true; you need a type of kind *. Kinds are the types of types: Int has kind *, Val a has kind *, Val has kind * -> *. That is, by itself Val is a type function which requires a parameter in order to become a full type.

like image 29
geekosaur Avatar answered Oct 11 '22 17:10

geekosaur


The error points to this part of the type definition:

val::(Val a)=> a

This syntax means, "for any instance a of the typeclass Val, the value of val is of type a." But then (1) Val isn't a typeclass and (2) the type a seems to come out of thin air.

What you may have intended to say is

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)
like image 43
Fred Foo Avatar answered Oct 11 '22 17:10

Fred Foo


Your problem is already solved, but I see you use GHC and sometimes — especially in the beginning — Hugs error messages may be somewhat easier to read, in this case:

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

This might actually have given you a first idea where to look. Mind you that I'm not advocating Hugs over GHC here, but as a Haskell beginner I think that the former provides more helpful error messages.

like image 29
Michael Kohl Avatar answered Oct 11 '22 17:10

Michael Kohl