Make Our Own Types
- built-in data types, e.g.,Boolean, Int, String, Maybe, etc.
- make our own data type? One way is to use the
data
keyword to define a type.
Data declaration
data Maybe a = Nothing | Just a
data
means that we're defining a new data type.- The part before the = is the
type
, which is Maybe a (vs. Maybe is a type constructor) - The parts after the = are
value constructors
.- They specify the different values that this type can have.
- The | is read as or. (Algebraic Data Type, or ADT)
- So we can read this as: the
Maybe a
type can have a value ofNothing
orJust a
. - Both the type name and the value constructors have to be capital cased.
Value constructors
are actually functions that ultimately return a value of a data type. And we can map them and partially apply them and everything.
import Data.Number (pi)
import Data.Ord (abs)
data Shape = Circle Number Number Number
| Rectangle Number Number Number Number
surface :: Shape -> Number
surface (Circle _ _ r) = pi * r * r
surface (Rectangle x1 y1 x2 y2) = (abs $ x2 - x1) * (abs $ y2 - y1)
Import and run it in repl:
> surface (Circle 10.0 20.0 10.0)
314.1592653589793
> surface $ Rectangle 0.0 0.0 100.0 100.0
10000.0
Type annotation of the surface
function: Circle is not a type, Shape is.
- 🆗 Shape -> Number
- 🆖 Circle -> Number
Pattern match against constructor, like Circle or Rectangle. We just write a constructor and then bind its fields to names.
We can improve our code by defining a new data type Point:
data Point = Point Number Number
data Shape = Circle Point Number
| Rectangle Point Point
we used the same name for the data type (Point before =) and the value constructor (Point after =). This has no special meaning, although it's common to use the same name as the type if there's only one value constructor.
Now the surface function can be written as below,
surface :: Shape -> Number
surface (Circle _ r) = pi * r ^ 2
surface (Rectangle (Point x1 y1) (Point x2 y2)) = (abs $ x2 - x1) * (abs $ y2 - y1)
In the rectangle pattern, we just used a nested pattern
matching to get the fields of the points.