Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return/yield a value from a recursive function in Elixir?

Tags:

elixir

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.

like image 684
Jukka Puranen Avatar asked Nov 21 '25 12:11

Jukka Puranen


2 Answers

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.

like image 101
whatyouhide Avatar answered Nov 24 '25 22:11

whatyouhide


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

like image 42
GavinBrelstaff Avatar answered Nov 24 '25 22:11

GavinBrelstaff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!