Ваш желаемый результат может быть получен путем определения
foo :: [a] -> [b] -> [[(a, b)]]
foo nums bools =
map (zip nums) . sequence $ replicate (length nums) bools
=
let n = length nums
in
[ zip nums bs | bs <- sequence $ replicate n bools]
и вызова
foo [1,2,3] [False, True]
Этот вызов эквивалентен
let nums = [1,2,3]
bools = [False, True]
n = 3
in
[ zip nums bs | bs <- sequence $ replicate n bools]
=
[ zip [1,2,3] bs | bs <- sequence $ replicate 3 [False, True]]
=
[ zip [1,2,3] (b:bs) | b <- [False, True]
, bs <- sequence $ replicate 2 [False, True]]
=
[ zip [1,2,3] (b:c:bs) | b <- [False, True]
, c <- [False, True]
, bs <- sequence $ replicate 1 [False, True]]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- sequence $ replicate 0 [False, True] ]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- sequence [] ]
=
[ zip [1,2,3] (b:c:d:bs) | b <- [False, True]
, c <- [False, True]
, d <- [False, True]
, bs <- [[]] ]
=
[ zip [1,2,3] (b:c:d:[]) | b <- [False, True]
, c <- [False, True]
, d <- [False, True] ]
т.е.
[ zip [1,2,3] [b,c,d] | b <- [False, True]
, c <- [False, True]
, d <- [False, True] ]
, и если вычислить это последнее выражение, мы также получим тот же результат.
Заполнение трех пробелов каждой возможной комбинацией двух доступных значений аналогично наличию всех возможных функций от 3 пробелов до 2значения, какими бы ни были эти пространства и значения.
Математики пишут эту функцию как 2 3 , и действительно, мы получаем 2^3 = 8
выходных данных.
edit: комбо sequence ... replicate
на самом деле просто переопределяет другое встроенное, replicateM
:
foo ns bs = map (zip ns) (replicateM (length ns) bs)
, потому что replicateM n a
похоже на sequence (replicate n a)
, но без создания промежуточного списка.
Для поклонников pointfree , таким образом, мы можем иметь
foo ns = map (zip ns) . replicateM (length ns)
= (.) ((map . zip) ns) ((replicateM . length) ns)
= ((.) . map . zip <*> replicateM . length) ns
т.е.
foo = (.) . map . zip <*> replicateM . length