Nested cartesian product of Haskell lists

后端 未结 3 1313
梦毁少年i
梦毁少年i 2021-02-06 02:03

I would like to make a method where I could give it a list of lengths and it would return all combinations of cartesian coordinates up to those lengths. Easier to explain with a

相关标签:
3条回答
  • 2021-02-06 02:41

    I bet your procedural solution would involve recursion. Our Haskell solution will involve recursion too.

    So, recursion. First the recursive case.

    cart (c : cs) = [i : r | i <- [0 .. c-1], r <- rcart]
      where rcart = cart cs
    

    Here we're just saying that for each possible initial co-ordinate, and each possible combination of cartesian co-ordinates from the remaining lengths, we do the obvious thing of combining the co-ordinate with the remaining co-ordinates.

    Then the base case.

    cart [] = [[]]
    

    You might think cart [] = []. I did at first. But think about what the recursive case requires from the base case.

    0 讨论(0)
  • 2021-02-06 02:57

    Umm..

    cart = sequence . map (enumFromTo 0 . subtract 1)
    

    It's reasonable to expect that a [[a]] -> [[a]] function doing what we expect already exists in the library. So if one is not familiar with sequence, finding it is a simple matter of hoogling it.

    Edit: as newacct pointed out:

    cart = mapM (enumFromTo 0 . subtract 1)
    

    This can also be found by feeding the previous solution to HLint.

    0 讨论(0)
  • 2021-02-06 02:58

    This can be solved recursively. First, the Cartesian product of nothing is {∅}:

    cart [] = [[]]
    

    (Or define just the 1-element form if the empty product is invalid:

    cart [x] = [[i] | i <- [0 .. x-1]]
    

    )

    Then, the Cartesian product of x:xs can be written as

    cart (x:xs) = [i:rest | i <- [0 .. x-1], rest <- cart xs]
    

    In general, if you what to write a function f that requires the list's length N, try to think of a way to make f(N) depends on smaller lists e.g. f(N - 1) only, then solve the base case f(0) or f(1) etc. This transforms the problem into a recursion that can be easily solved.

    0 讨论(0)
提交回复
热议问题