Как переписать алгоритм комбинаций Erlang в Elixir?

Я занимаюсь Elixir в течение последних нескольких недель. Я просто наткнулся на этот сжатый алгоритм сочетания "rel=" noreferrer" > в Erlang, который я попробовал переписать в Elixir, но застрял.

Версия Erlang:

comb(0,_) ->
  [[]];
comb(_,[]) ->
  [];
comb(N,[H|T]) ->
  [[H|L] || L <- comb(N-1,T)]++comb(N,T).

Elixir version Я придумал это, но это не правильно:

def combination(0, _), do: [[]]
def combination(_, []), do: []
def combination(n, [x|xs]) do
  for y <- combination(n - 1, xs), do: [x|y] ++ combination(n, xs)
end

Пример использования, с неправильными результатами:

iex> combination(2, [1,2,3])
[[1, 2, [3], [2, 3]]]

Любые указатели на то, что я делаю неправильно?

Спасибо!
Шон

Ответ 1

Вам нужно обернуть выражение for в круглых скобках, например, код Erlang.

def combination(n, [x|xs]) do
  (for y <- combination(n - 1, xs), do: [x|y]) ++ combination(n, xs)
end

Демо:

iex(1)> defmodule Foo do
...(1)>   def combination(0, _), do: [[]]
...(1)>   def combination(_, []), do: []
...(1)>   def combination(n, [x|xs]) do
...(1)>     (for y <- combination(n - 1, xs), do: [x|y]) ++ combination(n, xs)
...(1)>   end
...(1)> end
{:module, Foo,
 <<70, 79, 82, 49, 0, 0, 6, 100, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 137, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 2, 104, 2, ...>>,
 {:combination, 2}}
iex(2)> Foo.combination 2, [1, 2, 3]
[[1, 2], [1, 3], [2, 3]]