View Source Pipe Chains
Pipe Chains
Pipe Start
Styler will ensure that the start of a pipechain is a 0-arity function, a raw value, or a variable.
Enum.at(enum, 5)
|> IO.inspect()
# Styled:
enum
|> Enum.at(5)
|> IO.inspect()
If the start of a pipe is a block expression, styler will create a new variable to store the result of that expression and make that variable the start of the pipe.
if a do
b
else
c
end
|> Enum.at(4)
|> IO.inspect()
# Styled:
if_result =
if a do
b
else
c
end
if_result
|> Enum.at(4)
|> IO.inspect()
Add parenthesis to function calls in pipes
a |> b |> c |> d
# Styled:
a |> b() |> c() |> d()
Remove Unnecessary then/2
When the piped argument is being passed as the first argument to the inner function, there's no need for then/2
.
a |> then(&f(&1, ...)) |> b()
# Styled:
a |> f(...) |> b()
- add parens to function calls
|> fun |>
=>|> fun() |>
Add then/2
when defining and calling anonymous functions in pipes
a |> (fn x -> x end).() |> c()
# Styled:
a |> then(fn x -> x end) |> c()
Piped function optimizations
Two function calls into one! Fewer steps is always nice.
# reverse |> concat => reverse/2
a |> Enum.reverse() |> Enum.concat(enum) |> ...
# Styled:
a |> Enum.reverse(enum) |> ...
# filter |> count => count(filter)
a |> Enum.filter(filterer) |> Enum.count() |> ...
# Styled:
a |> Enum.count(filterer) |> ...
# map |> join => map_join
a |> Enum.map(mapper) |> Enum.join(joiner) |> ...
# Styled:
a |> Enum.map_join(joiner, mapper) |> ...
# Enum.map |> X.new() => X.new(mapper)
# where X is one of: Map, MapSet, Keyword
a |> Enum.map(mapper) |> Map.new() |> ...
# Styled:
a |> Map.new(mapper) |> ...
# Enum.map |> Enum.into(empty_collectable) => X.new(mapper)
# Where empty_collectable is one of `%{}`, `Map.new()`, `Keyword.new()`, `MapSet.new()`
# Given:
a |> Enum.map(mapper) |> Enum.into(%{}) |> ...
# Styled:
a |> Map.new(mapper) |> ...
# Given:
a |> b() |> Stream.each(fun) |> Stream.run()
a |> b() |> Stream.map(fun) |> Stream.run()
# Styled:
a |> b() |> Enum.each(fun)
a |> b() |> Enum.each(fun)
Unpiping Single Pipes
Styler rewrites pipechains with a single pipe to be function calls. Notably, this rule combined with the optimizations rewrites above means some chains with more than one pipe will also become function calls.
foo = bar |> baz()
# Styled:
foo = baz(bar)
map = a |> Enum.map(mapper) |> Map.new()
# Styled:
map = Map.new(a, mapper)
Pipe-ify
If the first argument to a function call is a pipe, Styler makes the function call the final pipe of the chain.
d(a |> b |> c)
# Styled
a |> b() |> c() |> d()