Fl4m3Ph03n1x

Fl4m3Ph03n1x

Can an elixir comprehensions return something other than a List?

Background

For the longest time I have been estranged to the magic lands of comprehensions in FP languages.
Now I am trying to pick it up.

Comprehensions use the for expression in Elixir:

How Scala does it

Most FP languages these days have comprehensions in one way or another. For the purposes of this discussion I am picking Scala because I think it looks somewhat familiar (syntax is fairly similar to that of elixir).

See the following comprehension (Scala):

for {
  a <- List(1, 2)
  b <- Set(2, 1)
} yield a * b

> List(2, 1, 4, 2)

This comprehension is the equivalent of (Elixir):

for a <- [1, 2], 
    b <- MapSet.new([2, 1]) do 
  a * b 
end

> [1, 2, 2, 4]

The Scala example returns a List because in Scala, the comprehension’s return type will be the type of the first enumerator (in this case a <- [1, 2]).

The Elixir example returns also a List. I have no idea why. Maybe they work in reverse? Let’s find out:

for {
  a <- Set(1, 2)
  b <- List(2, 1)
} yield a * b

> Set(2, 1, 4)

In this Scala example I switched things around. Lets see what Elixir returns:

for a <- MapSet.new([1, 2]), 
    b <- [2, 1] do 
  a * b 
end

> [2, 1, 4, 2]

It also returns a List

Questions

So, I am rather confused here. So here is my question:

  • In an Elixir comprehension with enumerators of different types, how do I know what the resulting type of the expression will be?

Marked As Solved

gregvaughn

gregvaughn

I mean the do block.

The types of the generator sources don’t come into play. They all must be Enumerable and the comprehension … enumerates them.

If it helps, you can envision a comprehension with a default into: [] if you leave it unspecified.

Also Liked

gregvaughn

gregvaughn

It’s always a list unless …
you give it an :into which can be any Collectable
you give it a :reduce in which case it is whatever type your block returns on last iteration

dimitarvp

dimitarvp

Sure, the :reduce option:

for i <- 1..4, reduce: 0 do
  acc -> acc + i
end

(returns 10)

LostKobrakai

LostKobrakai

for, Stream and Enum are all based on the Enumerable protocol, which disregards the actual input datatype in favor of an unbounded enumeration of values. The enumerable implementations essentially turn the raw data into something users of the protocol can reduce over.

dimitarvp

dimitarvp

Ah, I see you need an explanation of sorts. Oh well, I am just telling you what I’m seeing in the docs. You either return a list or a data structure you desire (:into and :reduce).

Fl4m3Ph03n1x

Fl4m3Ph03n1x

One could, for example, based on the concept of familiarity, also expect that the return type of the Elixir comprehension is also the type of the first enumerator.

So for example:

for a <- [1, 2], 
    b <- MapSet.new([2, 1]) do 
  a * b 
end

> Would return a MapSet here

This is not the case. I am trying to understand why.

I appreciate the enthusiasm, but before posting this question I also checked the documentation (I posted a link to some of it in my question as well, to invite readers to take a peek).

I personally believe that everyone’s time here is valuable, so its up to me to do proper homework before asking for help :smiley:

Where Next?

Popular in Questions Top

Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Werner
Hi, I’m using Ubuntu 18.04 and after updating to OTP-24.0 yesterday i have this warning when I run “mix local.hex”: 14:57:30.512 [warn] ...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
mathew4509
I have a list say x = ["23gh", "56kh", "97mh"] I would like to pass each element to Val in each iteration. Say, in iteration 1 -------...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

Other popular topics Top

TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement