Why can I use Maybe with record syntax, but not regular ADT syntax?
-
21-12-2019 - |
Question
I'm writing some data types in Haskell to represent formal English grammar.
data S = NP VP
So far so good, a sentence is just a noun phrase and a verb phrase. Marvel at the elegant beauty of algebraic data types!
I'll also define a determiner and adjective as:
data D = A | An | The
type Adj = String -- Too many adjectives for me to list, so I make it a type
-- synonym for String.
Now, I'm having issues defining NP, which is a noun with an optional determiner and adjective. My first natural instinct is to use Maybe:
data NP = Maybe D Maybe Adj N
which gives me the error:
Expecting one more argument to `Maybe' In the type `Maybe' In the definition of data
constructor `Maybe' In the data type declaration for `NP'
(Note that the error doesn't change based on whether or not I have imported Data.Maybe)
The only way I ever got this to work was by using record syntax:
data NP' = NP' {determiner :: Maybe D, adjective :: Maybe Adj, noun :: N}
Why does this only work when I use record syntax?
Solution
Try
data NP = NP (Maybe D) (Maybe Adj) N
You need to
- Begin with a constructor name: in this case
NP
- Apply only a single argument to
Maybe
which I've done by disambiguating it with parentheses - Denote 3 separate slots in the constructor, one for each component type
OTHER TIPS
I presume you meant to write (with the NP
data constructor):
data NP = NP Maybe D Maybe Adj N
In your example, NP
is being defined as a constructor with 5 arguments, the first of which is a bare "Maybe
". This doesn't work because Maybe
is a type that needs one type parameter, which is what the error message is telling you.
To get your desired interpretation, you need to surround the Maybe _
s with parentheses:
data NP = NP (Maybe D) (Maybe Adj) N