2015-10-28 2 views
1

В моей продолжающейся попытке поправиться на Haskell, я пытаюсь решить проблему, где я хотел бы создать ряд списковых этой формы:Есть ли способ генерировать серию программных программных списков в Haskell?

m2 = [[x1,x2] | x1 <- [2..110], x2 <- [x1..111]] 
m3 = [[x1,x2,x3] | x1 <- [2..22], x2 <- [x1..22], x3 <- [x2..24]] 
m4 = [[x1,x2,x3,x4] | x1 <- [2..10], x2 <- [x1..10], x3 <- [x2..10], x4 <- [x3..12]] 
... 

Где x1 < = x2. .. < = xn, число, следующее за m, - это длина подписок, а первые n - 1 термины ограничены одной и той же верхней границей, а n-й член ограничен некоторым большим числом.

Я мог бы написать все это вручную, но это не очень хорошая практика. Мне интересно, есть ли способ генерировать эти списки до определенного максимального значения m. Моей непосредственной мыслью был Template Haskell, но я не знаю достаточно об этом, чтобы определить, можно ли использовать его. Есть ли другое решение, которое ускользает от меня?

В псевдо-Haskell, что я ищу некоторый метод, который делает что-то вроде:

mOfN n bound term = [ [x1..xn] | x1 <- [2..bound], x2 <- [x1..bound], ..., xn <- [x(n-1)..term] ] 

Основная проблема заключается в том, что я не могу понять, как я бы динамически создавать x1, x2, и т. д.

ответ

4

Это вы что искали?

import Data.List (tails) 

mofn 0 xs = [ [] ] 
mofn m xs = [ y:zs | (y:ys) <- tails xs, zs <- mofn (m-1) ys ] 

т.е. mofn 3 [1..5] является:

[[1,2,3],[1,2,4],[1,2,5],[1,3,4],[1,3,5],[1,4,5],[2,3,4],[2,3,5],[2,4,5],[3,4,5]] 

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

Update

Это то, что вы ищете?

mofn' 1 lo hi bnd = [ [x] | x <- [lo..bnd] ] 
mofn' k lo hi bnd = [ x:ys | x <- [lo..hi], ys <- mofn' (k-1) x hi bnd ] 

mofn' 3 1 3 5 является:

[[1,1,1], [1,1,2], [1,1,3], [1,1,4], [1,1,5], 
[1,2,2], [1,2,3], [1,2,4], [1,2,5], 
[1,3,3], [1,3,4], [1,3,5], 
[2,2,2], [2,2,3], [2,2,4], [2,2,5], 
[2,3,3], [2,3,4], [2,3,5], 
[3,3,3], [3,3,4], [3,3,5] 
] 
+0

Это близко, но мне нужна функция, которая будет 1) дать мне подсписки где x1 = x2 = ... х и 2) использовать различные оценки для хпа, чем для другие xs. I.e., mofn 3 5 10 == [[x1, x2, x3] | x1 <- [1..5], x2 <- [1..5], x3 <- [1..10]]. –

+0

Но вы хотите x1 <= x2 <= x3, так что действительно mofn 3 5 10 == [[x1, x2, x3] | x1 <- [1..5], x2 <- [x1..5], x3 <- [x2..10]] - правильно? – ErikR

+0

В этом конкретном случае первое значение должно быть 2 для всех подписок, хотя решение, которое использует первое значение 1 для каждого, должно также работать, поскольку изменение первого значения - или удаление 1 - должно быть тривиальным , –

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