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?
Shape
is a type (and a type constructor).Float
is another type.Circle
andRectangle
are the value constructors for typeShape
.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
andRectangle
to be subtypes ofShape
.Using some advanced extensions like
GADTs
you can actually write something likefoo :: Circle -> Float
meaning that the argument is aShape
value which has been constructed as aCircle
. This requires some type-level techniques.Alternatively, a plain Haskell approach could be