Scoty
Can I check if value is in range in a guard clause
Hey,
I am currently reading Programming Elixir and I am doing one of the exercises where you should write a solution to the “I’m thinking of a number between 1 and 1000”
I have made it work, but I wanted to add a simple guard clause: I want to check if the passed number is actually in the passed range. As far as I have read only handful of functions and operators are allowed in guard clauses, but the ‘in’ is one of them.
So 1st I tried this:
def guess(actual, range) when (actual not in range), do: IO.puts "actual #{actual} is not in #{range}"
But I got: (ArgumentError) invalid args for operator “in”, it expects a compile-time proper list or compile-time range on the right side.
2nd I tried to make a list from the range:
def guess(actual, range) when (actual not in (Enum.to_list range), do: IO.puts "actual #{actual} is not in #{range}
And again I got the same error, this time saying that I the right side is the function itself instead the evaluation of it, which should be proper list ?!?
But this works(when the range is defined in the guard clause) :
def test(x) when(x not in 1..100) …
Most Liked
NobbZ
Well, at the point, where you already matched on min and max, and you can make it a compiletime range again for the guard:
iex(1)> defmodule M do
...(1)> def guess(n, min..max) when n in min..max, do: "Yeah, you won!"
...(1)> def guess(_, _), do: "There is no try!"
...(1)> end
iex(2)> M.guess 4, 1..1000
"Yeah, you won!"
iex(3)> M.guess 4, 1..3
"There is no try!"
I consider this slightly more readable than n > min and n < max (which I generally would prefer to write as min < n and n < max.
lpil
How about something like this?
def guess(actual, min..max) when actual < min or actual > max
Guards are very limited, and much of the fancy properties of in in guards is done at compile time using macros; because of this a compile time range literal can be used, but a runtime range value cannot.
NobbZ
Which is quite less readable and you have to remember to do it that way, while using the n in a..b approach just works.
Popular in Chat/Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









