Haskell cartesian product of infinite lists

前端 未结 4 1168
青春惊慌失措
青春惊慌失措 2021-02-13 00:13

I want to generate a vectorspace from a basis pair, which looks something like:

genFromPair (e1, e2) = [x*e1 + y*e2 | x <- [0..], y <- [0..]]
4条回答
  •  野性不改
    2021-02-13 00:55

    You could look at your space as a tree. At the root of the tree one picks the first element and in its child you pick the second element..

    Here's your tree defined using the ListTree package:

    import Control.Monad.ListT
    import Data.List.Class
    import Data.List.Tree
    import Prelude hiding (scanl)
    
    infiniteTree :: ListT [] Integer
    infiniteTree = repeatM [0..]
    
    spacesTree :: ListT [] [Integer]
    spacesTree = scanl (\xs x -> xs ++ [x]) [] infiniteTree
    
    twoDimSpaceTree = genericTake 3 spacesTree
    

    It's an infinite tree, but we could enumerate over it for example in DFS order:

    ghci> take 10 (dfs twoDimSpaceTree)
    [[],[0],[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7]]
    

    The order you want, in tree-speak, is a variant of best-first-search for infinite trees, where one assumes that the children of tree nodes are sorted (you can't compare all the node's children as in normal best-first-search because there are infinitely many of those). Luckily, this variant is already implemented:

    ghci> take 10 $ bestFirstSearchSortedChildrenOn sum $ genericTake 3 $ spacesTree
    [[],[0],[0,0],[0,1],[1],[1,0],[1,1],[0,2],[2],[2,0]]
    

    You can use any norm you like for your expanding shells, instead of sum above.

提交回复
热议问题