Search code examples
haskellalgebraic-data-types

Why can I use Maybe with record syntax, but not regular ADT syntax?


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

    1. Begin with a constructor name: in this case NP
    2. Apply only a single argument to Maybe which I've done by disambiguating it with parentheses
    3. Denote 3 separate slots in the constructor, one for each component type