Reading one of my Haskell books, I came across the sentence:
Data declarations always create a new type constructor, but may or may not create new data constructors.
It sounded strange that one should be able to declare a data type with no data constructor, because it seems that then one could never instantiate the type. So I tried it out. The following data declaration compiles without error.
data B = String
How would one create an instance of this type? Is it possible? I cannot seem to find a way.
I thought maybe a data constructor with name matching the type constructor would be created automatically, but that does not appear to be the case, as shown by the error resulting from attempting to use B as a data constructor with the declaration in scope.
Prelude> data B = String deriving Show
Prelude> B
<interactive>:129:1: error: Data constructor not in scope: B
Why is this data declaration permitted to compile if the type can never be instantiated? Is it permitted solely for some formal reason despite not having a known practical application?
I also wonder whether my book's statement about data types with no constructor might be referring to types declared via the type or newtype keywords instead of by data.
In the
typecase, type synonyms clearly do not use data constructors, as illustrated by the following.Prelude> type B = String Prelude>Type synonyms such as this can be instantiated by the constructors of the type they are set to. But I am not convinced that this is what my book is referring to as type synonyms do not seem to be declaring a new data type as much as simply defining an new alias for an existing type.
In the
newtypecase, it appears that types without data constructors cannot be created, as shown by the following error.Prelude> newtype B = String <interactive>:132:13: error: • The constructor of a newtype must have exactly one field but ‘String’ has none • In the definition of data constructor ‘String’ In the newtype declaration for ‘B’
type and newtype do not appear to be what the book is referring to, which brings me back to my original question: why it is possible to declare a type using data with no data constructor?