MHJ
MHJ

Reputation: 13

Beginning Haskell: Calling a simple function, matching a data structure

I am a little embarrassed to be asking such a banal question on here, but I am trying to follow the recent 'Beginning Haskell' book (Apress) as an introduction to Haskell, but the code does not work. I found the source code online, which was identical to my own, and that doesn't work either.

data Client = GovOrg     String
            | Company    String Integer Person String
            | Individual Person Bool
            deriving Show

data Person = Person String String Gender
            deriving Show

data Gender = Male | Female | Unknown
            deriving Show

clientName :: Client -> String
clientName (GovOrg name)                         = name
clientName (Company name _ _ _)                  = name
clientName (Individual (Person fName lName _) _) = fName ++ " " ++ lName

When I attempt to call the function with

clientName (GovOrg "NASA")

It returns "NASA". But when I try to call it with:

clientName (Company "Virgin")

Or:

clientName (Individual "Adam" "Smith") -- (or any other permutations of this function call)

The result is Type mismatch, and:

Probable cause: `Company' is applied to too few arguments

As you might be able to tell, I have a difficult time with the syntax at this stage, but I'm sure I would have a better time of it if I could get it to work in the first place. Is there something wrong with how I call the function from the interpreter?

Upvotes: 1

Views: 104

Answers (3)

ThreeFx
ThreeFx

Reputation: 7350

The problem is that you try to make a Company with Virgin as its only parameter. The parameters you actually need for a Company are a String and an Integer and a Person and another String.

clientName (Company "Virgin" 123 (Person "Three" "Fx" Unknown) "someString")

will work.

Upvotes: 1

Sibi
Sibi

Reputation: 48644

That's because you are not passing up the entire data. Try this:

λ> clientName (Company "Virgin" 3 (Person "fname" "lname" Male) "hello")
"Virgin"
λ> clientName (Individual (Person "Adam" "Smith" Male) True)
"Adam Smith"

Both Company and Individual are data constructors and you can inspect their type also:

λ> :t Individual
Individual :: Person -> Bool -> Client

So, for Construcing Individual you should pass Person and Bool type to it. Something like this builds up a Client type:

λ> let a = Individual (Person "Adam" "Roy" Male) True
λ> :t a
a :: Client

Upvotes: 4

Shoe
Shoe

Reputation: 76240

Both Company and Individual have data constructors that take more than 1 argument. Specifically Company also takes an Integer, a Person and a String; Individual also takes a Bool.

Not only that, but Individual takes a Person as first argument.

You should, for example, call:

clientName (Individual (Person "Adam" "Smith" Male) True)

Live demo

Upvotes: 0

Related Questions