Haskell, список натурального числа

Я - абсолютный новичок в Haskell, все же пытающемся понять, как это работает.

Я хочу написать свой собственный ленивый список целых чисел такой как [1,2,3,4,5...].

Для списка я записал

ones = 1 : ones

и при попытке хорошо работает:

*Main> take 10 ones
[1,1,1,1,1,1,1,1,1,1]

Как я могу сделать то же для увеличения целых чисел?

Я попробовал это, но это действительно перестало работать:

int  = 1 : head[ int + 1]

И после этого как я могу сделать метод, который умножает два потока? такой как:

mulstream s1 s2 = head[s1] * head[s2] : mulstream [tail s1] [tail s2]
11
задан Hellnar 21 March 2010 в 13:03
поделиться

4 ответа

Причины, по которым int = 1: head [int + 1] не работает:

  • head возвращает единственный элемент, но второй аргумент : должен быть список.
  • int + 1 пытается добавить список и число, что невозможно.

Самый простой способ создать список, отсчитывающий от 1 до бесконечности, - это [1 ..]

Для подсчета шагов, отличных от 1, вы можете использовать [firstElement, secondElement ..] , например для создания списка всех положительных нечетных целых чисел: [1, 3 ..]

Чтобы получить бесконечные списки вида [x, fx, f (fx), f (f (fx)), .. .] вы можете использовать iterate fx , например iterate (* 2) 1 вернет список [1, 2, 4, 16, ...] .

Чтобы применить операцию попарно к каждой паре элементов двух списков, используйте zipWith:

mulstream s1 s2 = zipWith (*) s1 s2

Чтобы сделать это определение более кратким, вы можете использовать форму без точек:

mulstream = zipWith (*)
21
ответ дан 3 December 2019 в 01:06
поделиться

В этом языке есть синтаксис:

take 10 [1,2..]

=> [1,2,3,4,5,6,7,8,9,10]

Вы даже можете делать разные шаги:

take 10 [1,3..]
=> [1,3,5,7,9,11,13,15,17,19]
3
ответ дан 3 December 2019 в 01:06
поделиться

Для натуральных чисел вы должны использовать карту:

num1 = 1 : map (+1) num1

Или понимания:

num2 = 1 : [x+1 | x <- num2]

Или, конечно:

num3 = [1..]
18
ответ дан 3 December 2019 в 01:06
поделиться

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

incr a = a : inrc (a+1)
lst = inrc 1

take 3 lst
=> [1,2,3]

Технически это называется накапливающей функцией (я полагаю), а затем все, что мы сделали, это сделали ее частный случай легко используемым с помощью 'lst'

Вы можете сойти с ума, делая такие вещи, как:

lst = 1 : incr lst where incr a = (head a) + 1 : incr (tail a)

take 3 lst
=> [1,2,3]

и так далее, хотя это, вероятно, опирается на некоторые вещи, которые вы еще не выучили (где) - судя по ОП - но это все равно должно читаться довольно легко.

О, точно, а затем умножение списка. Ну, вы можете использовать zipWith (*), как упоминалось выше, или изобрести колесо вот так (это веселее, поверьте мне :)

lmul a b = (head a * head b) : lmul (tail a) (tail b) 
safemul a b = take (minimum [len a, len b]) (lmul a b)

Причину safemul, я полагаю, вы можете выяснить, экспериментируя с функцией, но она связана с 'tail'. Проблема в том, что нет случая для пустого списка, несовпадающих списков и так далее, так что вам придется либо собирать вместе различные определения (lmul _ [] = []), либо использовать гвардию, или where и так далее... или придерживаться zipWith :)

.
4
ответ дан 3 December 2019 в 01:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: