Last active
October 27, 2016 18:33
-
-
Save tiagopog/08c3a241000e2ee9232a to your computer and use it in GitHub Desktop.
Elixir - Code Samples
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Demo do | |
| def greet(name) do | |
| IO.puts "Hello #{name} from Elixir" | |
| end | |
| def api_call do | |
| {:ok, "foo"} | |
| end | |
| end | |
| # Function call | |
| Demo.greet("Tiago") | |
| # Pattern matching | |
| {:ok, res} = Demo.api_call | |
| IO.inspect(res) | |
| # Pipe operator | |
| IO.inspect Enum.reverse(Enum.sort([2, 3, 1])) | |
| [2, 3, 1] |> Enum.sort |> Enum.reverse |> IO.inspect | |
| [6, 3, 2, 1, 7] | |
| # |> Enum.filter(&Integer.is_odd/1) | |
| |> Enum.map(fn i -> i * 2 end) | |
| |> Enum.reduce(&+/2) | |
| |> IO.inspect | |
| # Anonimous function | |
| add = fn a, b -> a + b end | |
| IO.inspect is_function(add, 2) #=> true | |
| IO.inspect is_function(add, 1) #=> false | |
| IO.inspect add.(2, 2) #=> 4 | |
| # Clojure | |
| add_two = fn a -> add.(a, 3) end | |
| IO.inspect add_two.(2) #=> 5 | |
| # Example of lexic scope in clojure | |
| x = 42 | |
| (fn -> x = 0 end).() | |
| IO.inspect x | |
| # Lists | |
| a = [1, 2, 3] | |
| b = [2, 3, 4, true] | |
| IO.inspect length(a) #=> 3 | |
| IO.inspect a ++ b #=> [1, 2, 3, 2, 3, 4, true] | |
| IO.inspect a -- b #=> [1] | |
| IO.inspect hd(a) | |
| IO.inspect tl(a) | |
| IO.inspect [1|[2|[3|[]]]] #=> [1, 2, 3] | |
| # hd [] or tl [], returns an ArgumentError | |
| # Tuples | |
| foobar = {:foo, :bar} | |
| IO.inspect tuple_size(foobar) #=> 2 | |
| IO.inspect elem(foobar, 1) #=> :bar | |
| IO.inspect put_elem(foobar, 1, :baz) #=> {:foo, :baz} | |
| list_to_tuple = fn(list, tuple) -> [head|tail] = list; list_to_tuple.(tail, Tuple.append(tuple, head)) end | |
| # Pattern matching | |
| {x, y, z} = {:hello, "world", 42} | |
| IO.inspect x | |
| IO.inspect y | |
| IO.inspect z | |
| [a, b, c] = [1, 2, 3] | |
| IO.inspect a | |
| # Pin operator | |
| x = 42 | |
| IO.inspect ^x = 42 # applies the pattern matching without assigning any value | |
| # Case | |
| case {1, 2, 3} do | |
| {4, 5, 6} -> "This won't match" | |
| {1, x, 3} -> "This will match and bind #{x} to x" | |
| _ -> "This would match any value" | |
| end |> IO.inspect | |
| # Case + pin operator | |
| x = 1 | |
| case 10 do | |
| ^x -> "This won't match" | |
| _ -> "This will match" | |
| end |> IO.inspect | |
| # Case + guard | |
| case {1, 2, 3} do | |
| {1, x, 3} when x > 2 -> "This won't match" | |
| {1, x, 3} -> "This will match" | |
| end |> IO.inspect | |
| # Case + anonimous funcion | |
| f = fn | |
| x, y when x > 0 -> x + y | |
| x, y -> x * y | |
| end | |
| IO.inspect f.(1, 3) #=> 4 | |
| IO.inspect f.(0, 2) #=> 0 | |
| # Cond | |
| cond do | |
| 1 + 1 == 3 -> "This is not true" | |
| 2 * 2 < 4 -> "This is not true" | |
| rem(9, 3) == 0 -> "This is true (displayed)" | |
| true -> "This is true (not displayed)" | |
| end |> IO.inspect | |
| # If/else and unless | |
| if nil do | |
| "This won't execute" | |
| else | |
| "This will execute" | |
| end | |
| is_number(if true do | |
| 1 + 2 | |
| end) |> IO.inspect #=> true | |
| # If (keyword list) | |
| if true, do: :foo, else: :bar #=> :foo | |
| if true, [do: :foo, else: :bar] #=> :foo | |
| if(true, do: :foo, else: :bar) |> IO.inspect #=> :foo | |
| # Binaries | |
| IO.puts "\n Binaries: \n" | |
| IO.inspect <<0, 1, 2, 3>> | |
| byte_size(<<0, 1, 2, 3>>) |> IO.inspect | |
| IO.inspect "foobar" <> <<0>> # Check String binary concatenating a byte | |
| IO.inspect <<256>> #=> truncated: <<0>> | |
| IO.inspect <<256 :: size(16)>> #=> 16-bit | |
| IO.inspect bit_size(<<256 :: size(16)>>) #=> 16 | |
| IO.inspect <<256 :: utf8>> #=> code point: Ã | |
| <<1, 2, x>> = <<1, 2, 3>> | |
| IO.inspect x | |
| <<1, 2, x :: binary>> = <<1, 2, 3, 4>> | |
| IO.puts x | |
| # Keyword list | |
| IO.puts "\n Keyword lists: \n" | |
| list = [{:foo, :bar}] | |
| IO.puts list[:foo] #=> :bar | |
| IO.puts list == [foo: :bar] #=> true | |
| # Map | |
| IO.puts "\n Maps: \n" | |
| map = %{a: 1, b: 2} | |
| IO.puts map.a #=> 1 | |
| IO.puts map.a #=> 2 | |
| IO.inspect %{map | b: 3} | |
| n = 1 | |
| map = %{n => 1} | |
| IO.puts map[n] | |
| %{^n => 2} = %{n => 2, a: 2} | |
| IO.puts n | |
| # Nested data structure | |
| IO.puts "\n Nested data structure: \n" | |
| users = [ | |
| john: %{name: "John", age: 27, languages: ["Erlang", "Ruby", "Elixir"]}, | |
| james: %{name: "James", age: 29, languages: ["Elixir", "F#", "Clojure"]} | |
| ] | |
| IO.puts users[:john].name #=> "John" | |
| users = put_in users[:john].name, "Joe" | |
| IO.inspect users | |
| users = update_in users[:john].languages, &List.delete(&1, "Erlang") | |
| IO.inspect users | |
| # Modules | |
| IO.puts "\n Modules: \n" | |
| defmodule Math do | |
| def sum(a, b) do | |
| do_sum(a, b) | |
| end | |
| defp do_sum(a, b) do | |
| a + b | |
| end | |
| def zero?(0) do | |
| true | |
| end | |
| # def + guard: | |
| def zero?(x) when is_number(x) do | |
| true | |
| end | |
| # The same could be achieved with the following syntaxe: | |
| def one?(1), do: true | |
| def one?(x) when is_number(x), do: false | |
| end | |
| IO.puts Math.sum(1, 2) #=> 3 | |
| IO.puts Math.zero?(0) #=> true | |
| IO.puts Math.zero?(1) #=> false | |
| IO.puts Math.one?(0) #=> false | |
| IO.puts Math.one?(1) #=> true | |
| # Capture functions: | |
| IO.puts "\n Capture functions: \n" | |
| fun = &Math.zero?/1 | |
| IO.puts fun.(0) #=> true | |
| (&:erlang.is_function/1).(fun) #=> true | |
| sum_one = &(&1 + 1) # the same as sum_one = fun x -> x + 1 | |
| IO.puts sum_one.(1) #=> 2 | |
| sum = &Math.sum(&1, &2) #=> the same as &Math.sum/2 or fun(a, b) -> Math.sum(a, b) end | |
| IO.puts sum.(2, 2) #=> 4 | |
| sum = fn(a, b) -> Math.sum(a, b) end | |
| IO.puts sum.(2, 3) #=> 5 | |
| # Default params: | |
| IO.puts "\n Default params: \n" | |
| defmodule Greeting do | |
| def say(foo \\ "Hello!") do | |
| foo | |
| end | |
| end | |
| IO.puts Greeting.say #=> "Hello!" | |
| IO.puts Greeting.say("Foobar!") #=> "Foobar!" | |
| defmodule Concat do | |
| def join(a, b \\ nil, sep \\ " ") | |
| def join(a, b, _sep) when is_nil(b) do | |
| a | |
| end | |
| def join(a, b, sep) do | |
| a <> sep <> b | |
| end | |
| end | |
| IO.puts Concat.join("Hello", "world") #=> Hello world | |
| IO.puts Concat.join("Hello", "world", "_") #=> Hello_world | |
| IO.puts Concat.join("Hello") #=> Hello | |
| # Recursion: | |
| IO.puts "\n Recursion: \n" | |
| defmodule Recursion do | |
| # Base base: | |
| def print_n_times(msg, n) when n <= 1 do | |
| IO.puts msg | |
| end | |
| # Other: | |
| def print_n_times(msg, n) do | |
| IO.puts msg | |
| print_n_times(msg, n - 1) | |
| end | |
| end | |
| Recursion.print_n_times('Hey!', 3) | |
| # Reduce: | |
| IO.puts "\n Reduce: \n" | |
| defmodule Reduce do | |
| def sum_list([head|tail], accumulator) do | |
| sum_list(tail, head + accumulator) | |
| end | |
| def sum_list([], accumulator) do | |
| accumulator | |
| end | |
| end | |
| IO.puts Reduce.sum_list([1, 2, 3], 0) #=> 6 | |
| IO.puts Enum.reduce([1, 2, 3], 0, fn (x, acc) -> x + acc end) | |
| IO.puts Enum.reduce([1, 2, 3], 0, &+/2) | |
| # Map: | |
| IO.puts "\n Map: \n" | |
| defmodule Map do | |
| def double_list([head|tail]) do | |
| [head * 2|double_list(tail)] | |
| end | |
| def double_list([]) do | |
| [] | |
| end | |
| end | |
| IO.inspect Map.double_list([1, 2, 3]) #=> [2, 4, 6] | |
| IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end) | |
| IO.inspect Enum.map([1, 2, 3], &(&1 * 2)) | |
| Enum.map_reduce(%{a: 1, b: 2}, %{}, fn({key, value}, acc) -> {%{key => value * 2}, Map.merge(acc, %{key => value * 2})} end) | |
| #=> {[%{a: 2}, %{b: 4}], %{a: 2, b: 4}} | |
| # Enumerable: | |
| IO.puts "\n Enumerable: \n" | |
| IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end) | |
| IO.inspect Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end) | |
| [1, 2, 3] |> Enum.map(&(&1 * 2)) |> Enum.sum |> IO.puts | |
| %{1 => 2, 3 => 4} |> Enum.map(fn {k, v} -> k * v end) |> Enum.sum |> IO.puts | |
| 1..3 |> Enum.reduce(&+/2) |> IO.puts | |
| # use UseMe | |
| defmodule UseImportRequire.UseMe do | |
| defmacro __using__(_) do | |
| quote do | |
| def use_test do | |
| IO.puts "use_test" | |
| end | |
| end | |
| end | |
| end | |
| # Working with files: | |
| File.open(file_path, [:read, :utf8], fn(file) -> | |
| IO.read(file, :line) | |
| end) | |
| path_to_file |> File.stream! |> Stream.map(&String.split/1) |> Enum.take(2) |> IO.inspect |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Fibonacci do | |
| def calculate(count) do | |
| calculate(1, 1, count - 1) | |
| end | |
| def calculate(a, _b, 0) do | |
| IO.puts a | |
| end | |
| def calculate(a, b, count) do | |
| calculate(b, a + b, count - 1) | |
| end | |
| end | |
| Fibonacci.calculate(4) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Demo do | |
| def greet(name) do | |
| IO.puts "Hello #{name} from Elixir" | |
| end | |
| def api_call do | |
| {:ok, "foo"} | |
| end | |
| end | |
| # Function call | |
| Demo.greet("Tiago") | |
| # Pattern matching | |
| {:ok, res} = Demo.api_call | |
| IO.inspect(res) | |
| # Pipe operator | |
| IO.inspect Enum.reverse(Enum.sort([2, 3, 1])) | |
| [2, 3, 1] |> Enum.sort |> Enum.reverse |> IO.inspect | |
| [6, 3, 2, 1, 7] | |
| # |> Enum.filter(&Integer.is_odd/1) | |
| |> Enum.map(fn i -> i * 2 end) | |
| |> Enum.reduce(&+/2) | |
| |> IO.inspect | |
| # Anonimous function | |
| add = fn a, b -> a + b end | |
| IO.inspect is_function(add, 2) #=> true | |
| IO.inspect is_function(add, 1) #=> false | |
| IO.inspect add.(2, 2) #=> 4 | |
| # Clojure | |
| add_two = fn a -> add.(a, 3) end | |
| IO.inspect add_two.(2) #=> 5 | |
| # Example of lexic scope in clojure | |
| x = 42 | |
| (fn -> x = 0 end).() | |
| IO.inspect x | |
| # Lists | |
| a = [1, 2, 3] | |
| b = [2, 3, 4, true] | |
| IO.inspect length(a) #=> 3 | |
| IO.inspect a ++ b #=> [1, 2, 3, 2, 3, 4, true] | |
| IO.inspect a -- b #=> [1] | |
| IO.inspect hd(a) | |
| IO.inspect tl(a) | |
| IO.inspect [1|[2|[3|[]]]] #=> [1, 2, 3] | |
| # hd [] or tl [], returns an ArgumentError | |
| # Tuples | |
| foobar = {:foo, :bar} | |
| IO.inspect tuple_size(foobar) #=> 2 | |
| IO.inspect elem(foobar, 1) #=> :bar | |
| IO.inspect put_elem(foobar, 1, :baz) #=> {:foo, :baz} | |
| list_to_tuple = fn(list, tuple) -> [head|tail] = list; list_to_tuple.(tail, Tuple.append(tuple, head)) end | |
| # Pattern matching | |
| {x, y, z} = {:hello, "world", 42} | |
| IO.inspect x | |
| IO.inspect y | |
| IO.inspect z | |
| [a, b, c] = [1, 2, 3] | |
| IO.inspect a | |
| # Pin operator | |
| x = 42 | |
| IO.inspect ^x = 42 # applies the pattern matching without assigning any value | |
| # Case | |
| case {1, 2, 3} do | |
| {4, 5, 6} -> "This won't match" | |
| {1, x, 3} -> "This will match and bind #{x} to x" | |
| _ -> "This would match any value" | |
| end |> IO.inspect | |
| # Case + pin operator | |
| x = 1 | |
| case 10 do | |
| ^x -> "This won't match" | |
| _ -> "This will match" | |
| end |> IO.inspect | |
| # Case + guard | |
| case {1, 2, 3} do | |
| {1, x, 3} when x > 2 -> "This won't match" | |
| {1, x, 3} -> "This will match" | |
| end |> IO.inspect | |
| # Case + anonimous funcion | |
| f = fn | |
| x, y when x > 0 -> x + y | |
| x, y -> x * y | |
| end | |
| IO.inspect f.(1, 3) #=> 4 | |
| IO.inspect f.(0, 2) #=> 0 | |
| # Cond | |
| cond do | |
| 1 + 1 == 3 -> "This is not true" | |
| 2 * 2 < 4 -> "This is not true" | |
| rem(9, 3) == 0 -> "This is true (displayed)" | |
| true -> "This is true (not displayed)" | |
| end |> IO.inspect | |
| # If/else and unless | |
| if nil do | |
| "This won't execute" | |
| else | |
| "This will execute" | |
| end | |
| is_number(if true do | |
| 1 + 2 | |
| end) |> IO.inspect #=> true | |
| # If (keyword list) | |
| if true, do: :foo, else: :bar #=> :foo | |
| if true, [do: :foo, else: :bar] #=> :foo | |
| if(true, do: :foo, else: :bar) |> IO.inspect #=> :foo | |
| # Binaries | |
| IO.puts "\n Binaries: \n" | |
| IO.inspect <<0, 1, 2, 3>> | |
| byte_size(<<0, 1, 2, 3>>) |> IO.inspect | |
| IO.inspect "foobar" <> <<0>> # Check String binary concatenating a byte | |
| IO.inspect <<256>> #=> truncated: <<0>> | |
| IO.inspect <<256 :: size(16)>> #=> 16-bit | |
| IO.inspect bit_size(<<256 :: size(16)>>) #=> 16 | |
| IO.inspect <<256 :: utf8>> #=> code point: Ã | |
| <<1, 2, x>> = <<1, 2, 3>> | |
| IO.inspect x | |
| <<1, 2, x :: binary>> = <<1, 2, 3, 4>> | |
| IO.puts x | |
| # Keyword list | |
| IO.puts "\n Keyword lists: \n" | |
| list = [{:foo, :bar}] | |
| IO.puts list[:foo] #=> :bar | |
| IO.puts list == [foo: :bar] #=> true | |
| # Map | |
| IO.puts "\n Maps: \n" | |
| map = %{a: 1, b: 2} | |
| IO.puts map.a #=> 1 | |
| IO.puts map.a #=> 2 | |
| IO.inspect %{map | b: 3} | |
| n = 1 | |
| map = %{n => 1} | |
| IO.puts map[n] | |
| %{^n => 2} = %{n => 2, a: 2} | |
| IO.puts n | |
| # Nested data structure | |
| IO.puts "\n Nested data structure: \n" | |
| users = [ | |
| john: %{name: "John", age: 27, languages: ["Erlang", "Ruby", "Elixir"]}, | |
| james: %{name: "James", age: 29, languages: ["Elixir", "F#", "Clojure"]} | |
| ] | |
| IO.puts users[:john].name #=> "John" | |
| users = put_in users[:john].name, "Joe" | |
| IO.inspect users | |
| users = update_in users[:john].languages, &List.delete(&1, "Erlang") | |
| IO.inspect users | |
| # Modules | |
| IO.puts "\n Modules: \n" | |
| defmodule Math do | |
| def sum(a, b) do | |
| do_sum(a, b) | |
| end | |
| defp do_sum(a, b) do | |
| a + b | |
| end | |
| def zero?(0) do | |
| true | |
| end | |
| # def + guard: | |
| def zero?(x) when is_number(x) do | |
| true | |
| end | |
| # The same could be achieved with the following syntaxe: | |
| def one?(1), do: true | |
| def one?(x) when is_number(x), do: false | |
| end | |
| IO.puts Math.sum(1, 2) #=> 3 | |
| IO.puts Math.zero?(0) #=> true | |
| IO.puts Math.zero?(1) #=> false | |
| IO.puts Math.one?(0) #=> false | |
| IO.puts Math.one?(1) #=> true | |
| # Capture functions: | |
| IO.puts "\n Capture functions: \n" | |
| fun = &Math.zero?/1 | |
| IO.puts fun.(0) #=> true | |
| (&:erlang.is_function/1).(fun) #=> true | |
| sum_one = &(&1 + 1) # the same as sum_one = fun x -> x + 1 | |
| IO.puts sum_one.(1) #=> 2 | |
| sum = &Math.sum(&1, &2) #=> the same as &Math.sum/2 or fun(a, b) -> Math.sum(a, b) end | |
| IO.puts sum.(2, 2) #=> 4 | |
| sum = fn(a, b) -> Math.sum(a, b) end | |
| IO.puts sum.(2, 3) #=> 5 | |
| # Default params: | |
| IO.puts "\n Default params: \n" | |
| defmodule Greeting do | |
| def say(foo \\ "Hello!") do | |
| foo | |
| end | |
| end | |
| IO.puts Greeting.say #=> "Hello!" | |
| IO.puts Greeting.say("Foobar!") #=> "Foobar!" | |
| defmodule Concat do | |
| def join(a, b \\ nil, sep \\ " ") | |
| def join(a, b, _sep) when is_nil(b) do | |
| a | |
| end | |
| def join(a, b, sep) do | |
| a <> sep <> b | |
| end | |
| end | |
| IO.puts Concat.join("Hello", "world") #=> Hello world | |
| IO.puts Concat.join("Hello", "world", "_") #=> Hello_world | |
| IO.puts Concat.join("Hello") #=> Hello | |
| # Recursion: | |
| IO.puts "\n Recursion: \n" | |
| defmodule Recursion do | |
| # Base base: | |
| def print_n_times(msg, n) when n <= 1 do | |
| IO.puts msg | |
| end | |
| # Other: | |
| def print_n_times(msg, n) do | |
| IO.puts msg | |
| print_n_times(msg, n - 1) | |
| end | |
| end | |
| Recursion.print_n_times('Hey!', 3) | |
| # Reduce: | |
| IO.puts "\n Reduce: \n" | |
| defmodule Reduce do | |
| def sum_list([head|tail], accumulator) do | |
| sum_list(tail, head + accumulator) | |
| end | |
| def sum_list([], accumulator) do | |
| accumulator | |
| end | |
| end | |
| IO.puts Reduce.sum_list([1, 2, 3], 0) #=> 6 | |
| IO.puts Enum.reduce([1, 2, 3], 0, fn (x, acc) -> x + acc end) | |
| IO.puts Enum.reduce([1, 2, 3], 0, &+/2) | |
| # Map: | |
| IO.puts "\n Map: \n" | |
| defmodule Map do | |
| def double_list([head|tail]) do | |
| [head * 2|double_list(tail)] | |
| end | |
| def double_list([]) do | |
| [] | |
| end | |
| end | |
| IO.inspect Map.double_list([1, 2, 3]) #=> [2, 4, 6] | |
| IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end) | |
| IO.inspect Enum.map([1, 2, 3], &(&1 * 2)) | |
| Enum.map_reduce(%{a: 1, b: 2}, %{}, fn({key, value}, acc) -> {%{key => value * 2}, Map.merge(acc, %{key => value * 2})} end) | |
| #=> {[%{a: 2}, %{b: 4}], %{a: 2, b: 4}} | |
| # Enumerable: | |
| IO.puts "\n Enumerable: \n" | |
| IO.inspect Enum.map([1, 2, 3], fn x -> x * 2 end) | |
| IO.inspect Enum.map(%{1 => 2, 3 => 4}, fn {k, v} -> k * v end) | |
| [1, 2, 3] |> Enum.map(&(&1 * 2)) |> Enum.sum |> IO.puts | |
| %{1 => 2, 3 => 4} |> Enum.map(fn {k, v} -> k * v end) |> Enum.sum |> IO.puts | |
| 1..3 |> Enum.reduce(&+/2) |> IO.puts | |
| # use UseMe | |
| defmodule UseImportRequire.UseMe do | |
| defmacro __using__(_) do | |
| quote do | |
| def use_test do | |
| IO.puts "use_test" | |
| end | |
| end | |
| end | |
| end | |
| # Working with files: | |
| File.open(file_path, [:read, :utf8], fn(file) -> | |
| IO.read(file, :line) | |
| end) | |
| path_to_file |> File.stream! |> Stream.map(&String.split/1) |> Enum.take(2) |> IO.inspect |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| defmodule Example.User do | |
| defstruct name: "Tiago", last_name: "Guedes", roles: [:admin, :owner] | |
| end | |
| IO.inspect %Example.User{} | |
| IO.inspect %Example.User{name: "Foobar"} | |
| foo = %Example.User{} | |
| foo = %{foo | name: "Foo"} | |
| IO.inspect foo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment