Haskell cartesian product of infinite lists

前端 未结 4 1165
青春惊慌失措
青春惊慌失措 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:54

    The data-ordlist package has some functions which are extremely useful for working with sorted infinite lits. One of these is mergeAllBy, which combines an infinite list of infinite lists using some comparison function.

    The idea is then to build an infinite list of lists such that y is fixed in each list, while x grows. As long as we can guarantee that each list is sorted, and that the heads of the lists are sorted, according to our ordering, we get a merged sorted list back.

    Here's a quick example:

    import Data.List.Ordered
    import Data.Ord
    
    genFromPair (e1, e2) = mergeAllBy (comparing norm) [[x.*e1 + y.*e2 | x <- [0..]] | y <- [0..]]
    
    -- The rest just defines a simple vector type so we have something to play with
    data Vec a = Vec a a
        deriving (Eq, Show)
    
    instance Num a => Num (Vec a) where
        (Vec x1 y1) + (Vec x2 y2) = Vec (x1+x2) (y1+y2)
        -- ...
    
    s .* (Vec x y) = Vec (s*x) (s*y)     
    norm (Vec x y) = sqrt (x^2 + y^2)
    

    Trying this in GHCi we get the expected result:

    *Main> take 5 $ genFromPair (Vec 0 1, Vec 1 0)
    [Vec 0.0 0.0,Vec 0.0 1.0,Vec 1.0 0.0,Vec 1.0 1.0,Vec 0.0 2.0]
    

提交回复
热议问题