2013-06-08 12 views
39

Próbuję funkcji i cube. Dlaczego square działa, gdy cube wysadzi w powietrze? fineNiespójne zachowanie funkcji

square = &1 * &1 
square.(5) 

Works podczas

cube = &1 * &1 * &1 
cube.(5) 

Zgłasza

** (ArithmeticError) bad argument in arithmetic expression 
    :erlang.*(#Function<erl_eval.6.82930912>, 5) 
    erl_eval.erl:572: :erl_eval.do_apply/6 
    src/elixir.erl:133: :elixir.eval_forms/3 
    /private/tmp/elixir-OVih/elixir-0.8.2/lib/iex/lib/iex/server.ex:19: IEx.Server.do_loop/1 
+2

wycięte z 'tag Erlang' z tego posta. To jest bardziej dla ludzi Elixir. –

Odpowiedz

44

Cytowanie Alexei Sholik na liście mailingowej eliksir-talk:

Normalnie, & 1 sprawia, że ​​tylko do działają prymitywne expressi na to należy. Innymi słowy, podchodzi AST do pierwszego rodzica i zastępuje tego rodzica fn.

Wyrażenia takie jak tej pracy po prostu grzywny:

&1 * &1 
&1 + 2 
&1 * &2

Ale to nie może być zaangażowany w bardziej skomplikowanego wyrażenia.

Na przykład, gdy piszesz:

&1 * &1 * &1

... piszesz coś w rodzaju:

fn x -> fn x -> x * x end * x end

nie ma dyskusji na temat eliksiru-core o tym, czy zachowanie &1 musi zostać zmodyfikowany, aby był mniej kłopotliwy w tych przypadkach.

Aby odpowiedzieć na konkretne pytanie, choć chcesz coś bardziej jak to:

cube = fn x -> x * x * x end

Jeśli chcesz użyć &1, można użyć prostego wyrażenia z math.pow/2:

cube = :math.pow(&1, 3)

. .. zauważ, że math.pow/2 zawsze przywraca płynność.

+0

im więcej używam eliksiru, tym bardziej uważam, że twórcy nie wiedzą, jak napisać parser. – PPPaul

53

Od 0.10.3 należy umieścić aplikację częściową między nawiasami, poprzedzoną operatorem &.

Nie będzie miał żadnych problemów z tej wersji:

iex> square = &(&1 * &1) 
iex> square.(5) 
25 
iex> cube = &(&1 * &1 * &1) 
iex> cube.(5) 
125 
+0

+1 - OP @Benjamin Tan - przeczytaj http://pragprog.com/book/elixir/programming-elixir na najnowsze – Vatsala

2

Według najnowszych Elixir documentation istnieją dwa sposoby tworzenia anonimowych funkcje:

# first one, more explicit 
cube = fn x -> x * x * x end 

#second one, syntactic sugar applied 
cube = &(&1*&1*&1) 

#calling them is the same 
IO.puts cube.(8) # should be 512 
Powiązane problemy