1
votes

I have created the type Contact, and I'm trying to create a function that takes 4 parameters (First Name, Last Name, Phone and State) and creates a contact and adds it to a list of existing contact.

type LastName = String
type FirstName = String
type Phone = String
type Contact = (Person, State)
data Person = Person Phone Name deriving (Show, Read)
type Name = (FirstName, LastName)
data State = Good | Bad

addContact :: Phone -> FirstName -> LastName -> State -> [Contact] -> [Contact]
addContact  c p n s [] = Contact (Person c (p,n)  ,s) : []
addContact c p n xs = Contact (Person c (p,n)  , s) : xs

I can't seems to find a solution on LYAH or SOF, I'm following exactly what this section says, particularly the section about shape: http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax but I'm getting the following compilation error:

• Data constructor not in scope:
        Contact :: (Person, [Char]) -> Contact

I tried to change the upper case for lowercase for the type and I still got undefined variable error compilation.

Is there something I'm missing here?

1
Your second and third type definitions make no sense, and would not compile. If you entered this source code you would get an error before reaching the function definition at all. Please edit the question to include the source code that actually fails. - amalloy

1 Answers

3
votes

Contact is not the type constructor, Contact is just an alias for (Person, State), so a 2-tuple, hence (,) is the data constructor:

addContact :: Phone -> FirstName -> LastName -> State -> [Contact] -> [Contact]
addContact c p n s xs = (,) (Person c (p,n)) s : xs

or less verbose:

addContact :: Phone -> FirstName -> LastName -> State -> [Contact] -> [Contact]
addContact c p n s xs = (Person c (p,n), s) : xs

You data type for Person is not valid, it should either be:

data Person = Person Phone Name deriving (Show, Read)

or you can work with a type alias, for example:

type Person = (Phone, Name)

then you thus implement this with:

addContact :: Phone -> FirstName -> LastName -> State -> [Contact] -> [Contact]
addContact c p n s xs = ((Person c (p, n)), s) : xs

or:

addContact :: Phone -> FirstName -> LastName -> State -> [Contact] -> [Contact]
addContact c p n s xs = ((c, (p, n)),s) : xs

finally the name type again has a problem, you can not write spaces between First and Name, and you should use parenthesis:

type Name = (FirstName, LastName)