elm-community / list-extra

Convenience functions for working with List.
http://package.elm-lang.org/packages/elm-community/list-extra/latest
MIT License
135 stars 59 forks source link

Add cartesianProduct2 #96

Closed mgold closed 6 years ago

mgold commented 6 years ago

This is a variation of cartesianProduct for when exactly two lists are being used. Instead of a list of lists -- the inner lists having length 2 -- the inner lists are replaced by pairs.

This came up in a project I was working on. Just as a sketch of utility, expanding a tree according to all possible transformations of an element:


type Tree a = Leaf a | Branch (Tree a) (Tree a)

transform : (a -> List a) -> Tree a -> List (Tree a)
transform f tree =
  case tree of
     Leaf x -> f x |> List.map Leaf
     Branch left right ->
        let
           lefts = transform f left
           rights = transform f right
        in case ( lefts, rights ) of
           ( [], [] ) -> [ tree ]

           ( _, [] ) ->
                    List.map (\bc -> Branch bc right) lefts

           ( [], _ ) ->
                    List.map (\bc -> Branch left bc) rights

           ( _, _ ) ->
                    cartesianProduct2 lefts rights
                        |> List.map (uncurry Branch)
pzp1997 commented 6 years ago

I'm pretty sure that cartesianProduct2 is just List.Extra.lift2 (,). Please correct me if I'm wrong. I think that having such a function might be encouraging an anti-pattern since typically you want to do something with the pairs for which lift2 is more suitable.

mgold commented 6 years ago

Yes, that's correct. Thank you for pointing that out.