3

this seems like a simple thing to do but I just don't seem to find a simple enough answer anywhere for me to grok.

So lets say I have an Elixir function like this:

   def fetch_card_ids(offset, total_cards) when offset < total_cards do
       url = "http://some.domanin?offset=#{offset}"
       response = HTTPotion.get url

       #return or yield response here

       fetch_card_ids(offset+24,total_cards)
   end

In C# I could yield a return value when iterating something which of course is not the same as recursion but nevertheless: can I do a similar thing in a recursive function in elixir?

Any help would be much appreciated of course.

2 Answers 2

5

If what you want to do is "stream" the response to the caller, then Streams are a good way to go. For example, you could use Stream.unfold/2:

def fetch_card_ids(offset, total_cards) do
  Stream.unfold offset, fn
    off when off < total_cards ->
      resp = HTTPotion.get(url)
      {resp, off + 24}
    _ ->
      nil
  end
end

This stream will "yield" responses every time it fetches them and stop when offset gets greater than total_cards.

Sign up to request clarification or add additional context in comments.

2 Comments

I'd say you typo'd at Stream.iterate there. You meant Stream.unfold, no?
@kaqqao whoops, nice catch! Fixed :)
2

How about using Streams this way

top = div(total_cards,24) +1 # integer division
result = Stream.map( 0..top, fn (offset) -> 
  url = "http://some.domanin?offset=#{24*offset}"
  HTTPotion.get url
  end ) |> Enum.to_list

Here Enum.to_list simply "yields" the list at the end but you can also process from that list in progressive time using things like Stream.take etc

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.