-- 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 Card
.
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
-
a
equalsSymbol
-
b
equalsShading -> Color -> Number -> Card
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.