Haskell Cons Оператор (:) - PullRequest
       20

Haskell Cons Оператор (:)

9 голосов
/ 28 апреля 2009

Я действительно новичок в Haskell (На самом деле я видел «Real World Haskell» от О'Рейли и подумал: «Хм, я думаю, я изучу функциональное программирование» вчера), и мне интересно: я могу использовать оператор конструкции для добавить элемент в начало списка:

1 : [2,3]
[1,2,3]

Я попытался создать пример типа данных, который я нашел в книге, а затем поиграть с ним:

--in a file
data BillingInfo = CreditCard Int String String
| CashOnDelivery
| Invoice Int
deriving (Show)

--in ghci
 $ let order_list = [Invoice 2345]
 $ order_list
[Invoice 2345]
 $ let order_list = CashOnDelivery : order_list
 $ order_list
[CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, CashOnDelivery, ...-

и т.д ... это просто повторяется вечно, это потому, что он использует ленивый оценка?

- РЕДАКТИРОВАТЬ -

хорошо, так что мне в голову давят, что order_list = CashOnDelivery: order_list не добавляет CashOnDelivery в исходный order_list, а затем устанавливает результат в order_list, но вместо этого является рекурсивным и создает бесконечный список, добавляя навсегда CashOnDelivery к началу себя. Конечно, теперь я помню, что Haskell - это функциональный язык, и я не могу изменить значение исходного order_list, так что я должен сделать для простого "прикрепить это к концу (или началу, что угодно) этого списка?" Сделать функцию, которая принимает список и BillingInfo в качестве аргументов, а затем возвращает список?

- РЕДАКТИРОВАТЬ 2 -

хорошо, основываясь на всех ответах, которые я получаю, и на невозможности передать объект по ссылке и переменным (как я привык) ... Я думаю, что только что задал этот вопрос преждевременно и что мне действительно нужно углубиться в функциональную парадигму, прежде чем я смогу действительно понять ответы на мои вопросы ... Я думаю, что я искал, как написать функцию или что-то, взяв список и элемент и возвращая список под тем же именем, чтобы функция могла вызываться более одного раза, без изменения имени каждый раз (как если бы это была фактически программа, которая добавляла бы фактические заказы в список заказов, и пользователь не имел бы каждый раз придумывать новое имя для списка, а вместо этого добавлять элемент в тот же список).

Ответы [ 12 ]

0 голосов
/ 28 апреля 2009

X: L означает «Создать список, начинающийся с X, за которым следуют элементы в списке, определяемом L».

Затем вы определяете order_list как CashOnDelivery, за которым следуют элементы в списке, определенном order_list. Это определение является рекурсивным, поэтому оценка списка продолжает возвращать CashOnDelivery. Ваш список содержит бесконечное количество значений CashOnDelivery , за которыми следует одно значение счета-фактуры.

0 голосов
/ 28 апреля 2009

Я думаю, вы имеете в виду "это потому, что он использует ленивый оценка"? Ответ да:

let ol = CashOnDelivery : ol

Это говорит нам о том, что ol содержит элемент CashOnDelivery, а затем результат выражения ol. Это выражение не оценивается до тех пор, пока не будет необходимо (отсюда: лень). Таким образом, когда ol печатается, CashOnDelivery будет напечатан первым. Только тогда будет определен следующий элемент списка, что приведет к бесконечному поведению.

...