Haskell Преобразование параметров в тип

Я создал тип «Контакт» и пытаюсь создать функцию, которая принимает 4 параметра (имя, фамилия, телефон и штат), создает контакт и добавляет его в список существующих контактов.

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

Кажется, я не могу найти решение для LYAH или SOF, я точно следую тому, что говорится в этом разделе, особенно в разделе о форме: http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax, но я получаю следующее ошибка компиляции:

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

Я попытался изменить верхний регистр на нижний регистр для типа, но все равно получил ошибку компиляции неопределенной переменной.

Есть ли что-то, что мне здесь не хватает?


person JavaDumbell    schedule 14.02.2021    source источник
comment
Ваши определения второго и третьего типов не имеют смысла и не будут компилироваться. Если вы введете этот исходный код, вы получите сообщение об ошибке еще до того, как достигнете определения функции. Пожалуйста, отредактируйте вопрос, чтобы включить исходный код, который на самом деле не работает.   -  person amalloy    schedule 14.02.2021


Ответы (1)


Contact не является конструктором типа, Contact — это просто псевдоним для (Person, State), поэтому 2-кортеж, следовательно, (,) — это конструктор данных:

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

или менее подробно:

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

Ваш тип данных для Person недействителен, он должен быть либо:

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

или вы можете работать с псевдонимом типа, например:

type Person = (Phone, Name)

то вы таким образом реализуете это с помощью:

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

наконец, тип имени снова имеет проблему, вы не можете писать пробелы между First и Name, и вы должны использовать круглые скобки:

type Name = (FirstName, LastName)
person Willem Van Onsem    schedule 14.02.2021
comment
Извините за плохое форматирование. Я внес предложенное вами исправление и попытался реализовать первую функцию и получил в результате следующую ошибку: Не удалось сопоставить тип «b0 -> (a0, b0)» с «(Человек, государство)». Ожидаемый тип: [Контакт ] Фактический тип: [b0 -> (a0, b0)] • В выражении: (,) (Person c (p, n) s) : xs В уравнении для 'addContact': addContact c p n s xs = (,) ( Лицо c (p, n) s) : xs | 10 | addContact c p n s xs = (,) (Person c (p,n) s) : xs | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - person JavaDumbell; 14.02.2021
comment
@930404JP: извините, опечатка, это (,) (Person c (p, n)) s - person Willem Van Onsem; 14.02.2021