I'm a newcomer to Haskell and am currently going through Real World Haskell. The book says the type constructor is used only in the type signature while the value constructor is used in actual code. It also gives an example of a declaration to show that the names for both are independent of each other. Why are two constructors needed in the first place, if only one of them is used in actual code? Since we would not use the type constructor in actual code, what purpose does the type constructor serve?
Specifies a set of row value expressions to be constructed into a table. The Transact-SQL table value constructor allows multiple rows of data to be specified in a single DML statement.
Data constructors are first class values in Haskell and actually have a type. For instance, the type of the Left constructor of the Either data type is: Left :: a -> Either a b. As first class values, they may be passed to functions, held in a list, be data elements of other algebraic data types and so forth.
In the area of mathematical logic and computer science known as type theory, a type constructor is a feature of a typed formal language that builds new types from old ones. Basic types are considered to be built using nullary type constructors.
Type and data type refer to exactly the same concept. The Haskell keywords type and data are different, though: data allows you to introduce a new algebraic data type, while type just makes a type synonym. See the Haskell wiki for details.
Maybe the names are a little bit misleading. A type constructor represents the name of the type you're declaring. They're called like that because they build types, not values: indeed, being (possibly) parameterized on type variables they define a family of types. They act something like C++'s templates and Java's generics. In data MyType a b = Constr a b
, MyType is a type constructor that takes two types a
and b
to build a new type (MyType a b)
.
A value constructor is the only part you would call a "constructor" in other (object oriented) languages, because you need it in order to build values for that type. So, in the previous example, if you take the value constructor Constr :: a -> b -> MyType a b
, you may build a value Constr "abc" 'd' :: MyType [Char] Char
.
It's a bit like saying "why do we need classes and objects if objects are the only thing that actually runs?"
The two sorts of constructors do different jobs. Type constructors go in type signatures. Value constructors go in runnable code.
In the simplest case, a type "constructor" is just a type name. In the simplest case, a type has only one value constructor. So you end up with things like
data Point = Point Int Int
You might say to yourself "now why the heck to I need to write Point
twice?"
But now consider a less trivial example:
data Tree x = Leaf x | Branch (Tree x) (Tree x)
Here Tree
is a type constructor. You give it a type argument, and it "constructs" a type. So Tree Int
is one type, Tree String
is another type, and so on. (Like templates in C++, or generics in Java or Eiffel.)
On the other hand, Leaf
is a value constructor. Given a value, it makes a 1-node tree out of it. So Leaf 5
is a Tree Int
value, Leaf "banana"
is a Tree String
value, and so on.
Similarly for Branch
. It takes two tree values and constructs a tree node with those trees as children. For example, Branch (Leaf 2) (Leaf 7)
is a Tree Int
value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With