2015-02-18 3 views
2

Предположим, у меня есть два бесконечных списка c и h.Бесконечный рекурсивный список из функции

Я также иметь функцию

f :: OLG -> Int -> Double -> Double -> Double -> Double -> Double,

, где OLG это тип данных я определил.

Я хотел бы построить третий бесконечный список, который имеет следующий вид

a :: [Double] 
a = [  0.0, 
    f m 0 ↑ (c!!0) (h!!0) w_ave, 
    f m 1 ↑ (c!!1) (h!!1) w_ave, 
    f m 2 ↑ (c!!2) (h!!2) w_ave, 
    f m 3 ↑ (c!!3) (h!!3) w_ave, 
    f m 4 ↑ (c!!4) (h!!4) w_ave, 
    f m 5 ↑ (c!!5) (h!!5) w_ave, 
    f m 6 ↑ (c!!6) (h!!6) w_ave, 
    ⋮, 
    f m i ↑ (c!!i) (h!!i) w_ave, 
    ] 

где m :: OLG, c :: [Double], h :: [Double] и w_ave :: Double. Uparrow () представляет собой заполнитель, который говорит, что третий аргумент f должен быть предыдущим элементом списка, который мы строим.

Я предполагаю, что существует чистый/рекурсивный способ сделать это, но, будучи новым для Hasekll, я не могу думать об этом. Возможно, мне нужно как-то использовать iterate?

Эта проблема напоминает мне немного стандартной реализации бесконечного списка чисел Фибоначчи

fibs = 0 : 1 : zipWith (+) fibs (tail fibs) 

в том, что последовательные элементы списка вычисляются путем применения функции к предыдущему списку элементов.

+4

Вот подсказка: начать с формой 'а = 0,0: zipWith4 г? ? ? ? 'где' g' является функцией, а четыре '?' - это четыре списка. Затем определите, что должно быть 'g' и четыре'? 'S (один из' '' s будет ссылаться на 'a'). –

+0

@ReidBarton, отличная подсказка. Я смог его решить! Должен ли я публиковать отдельный ответ или просто редактировать свой оригинальный пост? – spencerlyon2

+0

@ spencerlyon2 Отдельный ответ. Вы также можете принять его через некоторое время. – Shoe

ответ

4

Благодаря подсказке от @ReidBarton я смог решить эту проблему. Вот что я придумал:

ПРИМЕЧАНИЕ: как указано в @Jeffrey, чтобы упростить код и разрешить частичное приложение определять функцию g для нас, я переопределил f так, чтобы i-й элемент a будет f m w_ave i ↑ (c!!i) (h!!i) (я переместил w_ave как второй аргумент вместо последнего).

Это означает, что тип F теперь f :: OLG -> Double -> Int -> Double -> Double -> Double -> Double

alist :: OLG -> [Double] -> [Double] -> [Double] 
alist m cs hs = as 
    where as = 0.0 : zipWith4 (f m w_ave) [0..] as cs hs 
+0

Вы можете выразить 'g' в терминах' f', если вы переместите 'w_ave' после' m': 'g = f m w_ave'. – Shoe

+0

@Jefffrey, большой пункт. См. Комментарий выше. – spencerlyon2

+0

Возможно, вы также должны использовать '[0 ..]' вместо '[1 ..]'. – Shoe

Смежные вопросы