Search code examples
haskelltype-declarationvalue-constructor

Why are types declared in value constructors not types in Haskell?


Suppose I have the following value constructor:

data Shape = Circle Float Float Float | Rectangle Float Float Float Float

Now I can run:

ghci> :t Circle
Circle :: Float -> Float -> Float -> Shape

Now I can write a type declaration

surface :: Shape -> Float

But I can't type a type declaration

surface :: Circle -> Float

This is because "Circle is not a type, Shape is"

My question is: Why are types declared in value constructors not types in Haskell?


Solution

  • data Shape = Circle Float Float Float | Rectangle Float Float Float Float
    

    Shape is a type (and a type constructor). Float is another type.

    Circle and Rectangle are the value constructors for type Shape.

    I guess that your confusion comes from OOP subtyping -- note that Haskell has no analogous to that. The above does not declare two types Circle and Rectangle to be subtypes of Shape.

    Using some advanced extensions like GADTs you can actually write something like foo :: Circle -> Float meaning that the argument is a Shape value which has been constructed as a Circle. This requires some type-level techniques.

    Alternatively, a plain Haskell approach could be

    data Circle = Circle Float Float Float
    data Rectangle = Rectangle Float Float Float Float
    data Shape = Scircle Circle | Srectangle Rectangle