1
votes

Reading through a book I came across Haskell Bool Type which is

data Bool = True | False

As I understand in this case True and False are values and the expression of below type is valid

c = True

Later on, when I wanted to create a new type I forgot to name the Value constructor and created the following type.

data Cartesian2D = Double Double

In this case, Haskell (GHCI) did not complain.

But when I tried to construct a value like

x = 1.0 2.0 

and

x = Double Double

in both cases, Haskell returned an error.

In this case,

  1. Is the type Cartesian2D valid?

  2. if the type is not valid, why did Haskell not complain when I was constructing the type? but only informed me while constructing a value of the type.

1

1 Answers

11
votes

Data constructors like True and type constructors like Bool exist in separate namespaces. True is an example of a nullary constructor, taking no arguments. As such, the definition

data Cartesian2D = Double Double

defines a type constructor named Cartesian2D and a unary data constructor named Double. Non-nullary data constructors behave much like functions, taking arguments to return a value of their associated type. Here, Double behaves like a function of type Double -> Cartesian2D (again, note that the type constructor Double and the type constructor Double are distinct).

x = Double 1.0
y = Double 2.0

To create a "real" Cartesian point type that stores two doubles, try something like

data Cartesian2D = Point Double Double

which defines a data constructor Point that takes two values of type Double to create a value of type Cartesian2D.


If you are at all bothered by the fact that nullary data constructors are somehow "special" in not behaving like functions (i.e., you don't have to call True, it just is a value), you can think of nullary constructors as being shorthand for unary constructors that take a dummy argument of type ():

True :: Bool

is short for

True () :: () -> Bool

which would always have to be used as True () otherwise.