-- Features type Symbol = Triangle | Circle | Wave type Shading = Striped | Empty | Solid type Color = Red | Green | Purple type Number = One | Two | Three -- Card type Card = Card Symbol Shading Color Number -- Deck type alias Deck = List Card -- A deck has 81 cards, which is all the possible combinations to combine -- the four features in a card. Each card is unique and exists only once in the deck. -- Now the question: How can I generate the deck? -- (it does not have to be random (yet)). -- extending the question: How can I generally generate all possible -- combinations of a product type?
deck : Deck deck = let listSymbol = [Triangle,Circle,Wave] listShading = [Striped,Empty,Solid] listColor = [Red,Green,Purple] listNumber = [One,Two,Three] productApply : List a -> List (a -> b) -> List b productApply l1 = List.map (\b -> l1 |> List.map b) >> List.concat in Card |> List.singleton |> productApply listSymbol |> productApply listShading |> productApply listColor |> productApply listNumber
Hey thanks very much for your reply. Can you explain what productApply does a little, because I am not sure I understand this, well. Thanks!
Well, essentially what you are asking for is called a “cartesian product” (thats the mathematical term for it)
product : List a -> List b -> List (a,b) product l1 l2 = l2 |> List.map (\b -> l1 |> List.map (\a -> (a,b))) |> List.concat
with this we would get something like
listSymbol |> product listShading |> product listColor |> product listNumber |> List.map (\(number,(color,(shading,symbol))) -> Card symbol shading color number )
This got me thinking. Instead of returning a tuple I could immediately apply the value to the function
productApply : List a -> List (a->b) -> List b productApply l1 l2 = l2 |> List.map (\b -> l1 |> List.map (\a -> b a)) |> List.concat
Note that b is now a function.
At the end I removed
l2 and replaced
(\a -> b a) with
b as that’s essentially the same. This last step is just how I like my code to look like, so you don’t have to do it.
Thanks. So the elements of l2 become b. So for every element b you map a function that takes every elements a from l1 and applies a to b. Then you flatten the result. but where is List (a -> b) coming from? And is List (a->b) a list of functions from a to b?
The constructor function
Card is of type
Symbol -> Shading -> Color -> Number -> Card.
So in the first step
Card |> List.singleton is the
List (a -> b) where
Shading -> Color -> Number -> Card
Possibly easier to read and debug https://ellie-app.com/7pRVnPVm8Z5a1
Another one using List.Extra https://ellie-app.com/7pSvFtsTcP3a1
Thank you all. I think I understand now!
This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.