Reputation: 83
I was wondering if it is possible to do something like this in Haskell
data Word = Det String | Adj String | Noun String | Verb String | Adverb String
data NounPhrase = Noun | Det Noun
If I'm going about this wrong, what I am trying to say is - a "Word" is either a "Det", "Adj", "Noun", etc. and a "NounPhrase" is a "Noun" OR a "Det" followed by a "Noun".
When I try to do this I get the error: "Undefined type constructor "Noun""
How can I go about this so it performs as stated above.
Upvotes: 1
Views: 251
Reputation: 1693
When you define an algebraic data type like
data MyType = Con1 String | Con2 Int
then Con1
and Con2
are data constructors which themselves are
functions Con1 :: String -> MyType
and Con2 :: Int -> MyType
.
Your example is having 2 problems:
Det
and Noun
) for Word
and for NounPhrase
.
So you need to choose different names for the constructors of
NounPhrase
.Det Noun
does not make sense, since Noun
is a data
constructor, whereas the argument of Det
needs to be a type, e.g., String
.See Constructors in Haskell to help clear things up.
Upvotes: 4
Reputation: 28539
You are confusing types and value constructors. When you say
data Word = Det String | Adj String | Noun String | Verb String | Adverb String
You define the type Word
as being one of a number of forms, for example
Det String
says that Det
is a constructor that takes a String
and gives you back a value of type Word
. Same goes with Noun
which is defined to be a constructor for Words and not a type.
There are various ways you might encode what you want in Haskell. By far the simplest is to use
data Word = Det String | Adj String | Noun String | Verb String | Adverb String
data NounPhrase = JustNoun String | Compound String String
and this is the "learning Haskell" way of doing it. It is "stringly typed", but is probably sufficient for your purposes.
Upvotes: 2