Рассмотрим следующий код, который я написал:
import Control.Monad
increasing :: Integer -> [Integer]
increasing n
| n == 1 = [1..9]
| otherwise = do let ps = increasing (n - 1)
let last = liftM2 mod ps [10]
let next = liftM2 (*) ps [10]
alternateEndings next last
where alternateEndings xs ys = concat $ zipWith alts xs ys
alts x y = liftM2 (+) [x] [y..9]
Где ' увеличение n
' должно возвращать список n-значных чисел, чьи номера увеличивать (или оставаться неизменным) слева направо.
Есть ли способ упростить это? Использование « let
» и « liftM2
» везде мне кажется некрасивым. Думаю, мне не хватает чего-то важного в монаде списка, но я не могу от них избавиться.