Вот пошаговое объяснение:
let a = 2
b = 1:[i * 2 | i <- b]
f a = 1:[i * a | i <- (f a)]
in take (a+2) (f (head (tail b) ))
Там есть две разные переменные, называемые a
, и одна затеняет другую, поэтому сначала давайте переименуем одну из них, чтобы случайно не перепутать их:
let outer_a = 2
b = 1:[i * 2 | i <- b]
f a = 1:[i * a | i <- (f a)]
in take (outer_a+2) (f (head (tail b) ))
Теперь мы можем подставить outer_a
и оценить +
:
let b = 1:[i * 2 | i <- b]
f a = 1:[i * a | i <- (f a)]
in take 4 (f (head (tail b) ))
Перепишите списки в терминах map
:
let b = 1:map (* 2) b
f a = 1:map (* a) (f a)
in take 4 (f (head (tail b) ))
Использовать iterate
вместо явной рекурсии:
let b = iterate (* 2) 1
f a = iterate (* a) 1
in take 4 (f (head (tail b) ))
Оцените первые два шага b
:
let b = 1:2:iterate (* 2) 4
f a = iterate (* a) 1
in take 4 (f (head (tail b) ))
Заменить на b
:
let f a = iterate (* a) 1
in take 4 (f (head (tail (1:2:iterate (* 2) 4)) ))
Оценить tail
:
let f a = iterate (* a) 1
in take 4 (f (head (2:iterate (* 2) 4) ))
Оценка head
:
let f a = iterate (* a) 1
in take 4 (f 2)
Заменить на f a
:
take 4 (iterate (* 2) 1)
Оцените iterate
несколько раз:
take 4 (1:2:4:8:iterate (* 2) 16)
Оценить take
:
[1,2,4,8]
И мы закончили.