Sequential function calls

I would like to do a sequential call in a ul view-statement.

view model =
    div [ class "tarot" ]
        [ div [ id "counter" ]
            [ text "Counter: "
            , span [] [ text "0" ]
            , text " seconds"
            ]
        , h1 [ class "center" ] [ text "TAROT CARD GAME" ]
        , ul []
            (List.map (initializeCards model.selectedCard) model.cards)
            (List.map (initializeCards model.selectedCard) model.cards)
        ]

More exactly, in

ul []
   (List.map (initializeCards model.selectedCard) model.cards)
   (List.map (initializeCards model.selectedCard) model.cards)
]

How can I call a function n times in a row; or, more generally, call a sequence of different functions, as in a Do statement in Haskell?

As another example,

initializeN n f =
    let
        stop = 1
    in
        if stop <= n then
            **Do**
                 f                                           -- Call function
                 initializeN (decrement n) f   -- Recursion with decreased value

in which,

initializeN f 5

Would call f five times.

Hi!

I’m not sure if I completely understood what you’re trying to accomplish, so let me talk through it a little bit to make sure I understood…

Elm is pure, so “calling a function” doesn’t have side-effects. And Elm, unlike Haskell, also doesn’t have a Monad interface to represent side-effects. So there’s not going to be any purpose to calling a function multiple times unless you are using different arguments. I’m thinking in your examples, you want to produce some values, and then use the values multiple times?

In the case of the ul example, you want to end up with two displayed copies of each card? If so, I’d do it like this:

let
    cardViews = List.map (initializeCards model.selectedCard) model.cards
in
Html.ul []
    (List.concat [cardViews, cardViews])

In your initializeN example, f would return the same value on every call, right? So then you can use List.repeat (and in your example, f isn’t passed an argument, so it’s really just a value, not a “function”):

List.repeat 5 f

Or if there were some arguments to f:

List.repeat 5 (f arg1 arg2 arg3)

If I’m wrong about the above and you do want different input values passed to each call, then you’d use List.map if you have a list of input values, possibly with List.range if you need to create a list of indices

cardFromIndex : Int -> Card
cardFromIndex i = ...

List.map cardFromIndex (List.range 1 52)

or List.indexedMap if you have a list of input values and want indices.

1 Like

You nailed it. Can you read minds? Because you totally got my point haha :slight_smile:

Yeah, so I was trying to instantiate pair of cards, because I’m creating that old memory-game, in which one have to find the matching pairs of cards.

In the future, I plan to incorporate random positions to the cards.

So far, I managed to flip the cards, only.

You can check the entire project here Elm-FlippingCards, or the live version here.

Thank you.

1 Like

Ah, great :smiley:

This brings to mind another way you might want to consider organizing it where you make a pair for each card and then combine them instead of making a full set of cards and then copying the full set:

let
    makeCardPair card =
        [ initializeCards model.selectedCard card
        , initializeCards model.selectedCard card
        ]
        -- or instead you could use:
        -- List.repeat 2 (initializeCards model.selectedCard card)
in
List.concatMap makeCardPair model.cards

Good luck w/ your game!

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.