简体   繁体   中英

Relation Between the Different Types in Haskell

From my understanding, there are 4 "types" in Haskell:

  • Algebraic data type with data
  • Data type constructors (what's after the = in the data types; not types technically, I don't think)
  • Type alias with type
  • Typeclasses with class
  • Type instances with instance

The questions are:

  1. If there are more kinds of types in Haskell. If so, what there relations are.
  2. What the difference is between a data type and a class typeclass. They seem similar, though obviously they have some different features. Same with (3).
  3. What the difference is between a data type and a instance typeclass instance.

I am new to Haskell.

data and newtype introduce new types (or type constructors actually - Maybe isn't a type, but Maybe a is a type for any a that is a type).

A data declaration introduces both a new type (what's left of the = ) and a way to represent data of that type (what's right of the = ).

So for example, if you have a data declaration like this:

data SomeType = SomeConstructor

Then you have introduced a new type called SomeType , and a way to construct values of SomeType , namely the constructor SomeConstructor (which incidentally doesn't have any parameters, so is the the only value inhabiting this type).

A typeclass doesn't do either of these things (and neither does an instance ). A typeclass introduces a constraint and a bunch of polymorphic functions that should be available if that constraint is met. An instance is basically saying "this type meets this constraint" by providing an implementation for these functions. So a class isn't really introducing new types, it's just a way to provide ad-hoc polymorphism for existing types.

For instance, the Show typeclass is roughly this:

class Show a where -- a is an instance of Show if
   show :: a -> String -- it has a function called show with this signature

(Note that the actual Show class in Prelude doesn't quite look like this)

show now has the type Show a => a -> String , which you can read as

for all a, if they meet the constraint Show (or alternatively, if they are an instance of Show ) this is a function that takes an a and returns a string

An instance for this would look like this

instance Show SomeType where
  show SomeConstructor = "SomeConstructor"

Which means

SomeType satisfies the constraint Show , and I'll show you how by providing an implementation of show

That's roughly the gist of it. There are language extensions that allow somewhat more involved things to happen with type classes and instances, but you don't need to worry about that for now.

You may have heard of kinds , which are the "types of types" in Haskell. A type is something with kind * , which represents things that can have values:

> :kind Int
Int :: *
> :kind Char
Char :: *

Type constructors are things with kind * -> * ; a type constructor takes a type (something of kind * ) and returns another type.

> :kind Maybe
Maybe :: * -> *
> :kind []
[] :: * -> *

Applying a type constructor gives you a new thing of kind * :

> :kind Maybe Int
Maybe Int :: *
> :kind [] Float
[] Float :: *

(The parser allow [Foo] as a special case for [] Foo .)

There are other things that are kinds as well. One of them is Constraint , and you create a Constraint with a constraint constructor (otherwise known as a type class). Give a constraint constructor a type, and you get back a constraint.

> :kind Show
Show :: * -> Constraint
> :kind Show Int
Show Int :: Constraint
> :kind Show (Int -> Char)
Show (Int -> Char) :: Constraint

(Note that the latter is properly kinded even though no instance for Int -> Char is defined.)


In this light, => looks something like an operator, rather than just special syntax. Its arguments are a "list" of constraints (albeit using universally quantified type variables instead of concrete types) and a type, and its return value is a "constrained" type (let's pretend there is a kind ConstrainedType in addition to * , * -> * , and Constraint ).

:t show
show :: Show a => a -> String

-- Taking extreme liberties with syntax
-- :k (=>)
-- (=>) :: [Constraint] -> * -> ConstrainedType
-- A section?
-- :k (Show a =>)
-- (Show a =>) :: * -> ConstrainedType
-- :k (Showa => * -> String)
-- Show a => a -> String :: ConstrainedType

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM