In this case, data type
and type
are synonymous. However, I will admit that confusion can arise because Haskell has two keywords data
and type
that perform two very different functions. To try to keep the distinction clear, it's important to be mindful of the context. Whenever you're talking about the types in a signature or types in general, the terms "data types" and "types" almost always refer to the same thing. Whenever you're talking about declaring types in code, there can be a difference.
A type declared with data
is a new, user-defined type, so you can do things like
data Status = Ready | NotReady | Exploded
Where Ready
, NotReady
and Exploded
are new constructors not included in Haskell.
On the other hand, there is the type
keyword that simply creates an alias to an existing type:
type Status = String
ready, notReady, exploded :: Status
ready = "Ready"
notReady = "NotReady"
exploded = "Exploded"
Here, the Status
is simply an alias for String
, and anywhere you use String
you can use a Status
and vice-versa. There aren't any constructors, just pre-built values to use. This approach is far less safe and if you use something like this you will run into bugs at some point. type
declarations are commonly used to make certain arguments more clear about what they're for, such as
type FilePath = String
This is a built-in alias in GHC, and if you see a function
doSomething :: FilePath -> IO ()
Then you know immediately to pass it a file name, compared to
doSomething :: String -> IO ()
You have no idea what this function does, other than "something". They're also commonly used to reduce typing, such as:
type Point = (Double, Double)
Now you can use Point
instead of (Double, Double)
in your type signatures, which is shorter to write and more readable.
To summarize, data
declares an entirely new type, completely custom just for you, and type
should be renamed alias
so that people stop getting confused about them when they first approach Haskell.