Matt Gibson
Matt Gibson

Reputation: 83

Use custom data type to define new data type in haskell

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

Answers (2)

Peter
Peter

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:

  1. You're using the same data constructor for different types. Since data constructors are functions that yield a value of a specific type, you can't use the same data constructors (Det and Noun) for Word and for NounPhrase. So you need to choose different names for the constructors of NounPhrase.
  2. 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

Philip JF
Philip JF

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

Related Questions