listhaskelltypesconstruction

Haskell Converting paramaters into type


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?


Solution

  • 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)