2017-10-10 9 views
2

「を」defimplする機能を渡します。は、私は次のコードしているオプション

だから私はこれを実行しようとしました:

# constants.ex 
defmodule Constants do 
    @enumerables [List, Map] 
    def enumerables, do: @enumerables 
end 

# reversible.ex 
import Constants, only: [enumerables: 0] 

defprotocol Reversible do 
    def reverse(term) 
end 

defimpl Reversible, for: enumerables() do 
    def reverse(term), do: Enum.reverse(term) 
end 

そして、私はエラーを持っている:

== Compilation error in file lib/reversible.ex == 
** (FunctionClauseError) no function clause matching in Module.concat/2 

    The following arguments were given to Module.concat/2: 

     # 1 
     Reversible 

     # 2 
     [List, Map] 

    (elixir) lib/module.ex:562: Module.concat/2 
    lib/reversible.ex:8: (file) 
    (elixir) lib/kernel/parallel_compiler.ex:121: 
     anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1 

この問題を解決するためにどのように?

答えて

3

defimplは、for引数at compile time(マクロ引数)and if it's a list, it recurses over all items of the listの値をチェックします。変数はリテラルリストではないので、defimplはリストとして扱われません。

あなたは、リストを反復処理し、上defimplを呼び出すことによってこの問題を回避することができ、それぞれ自分自身:

# constants.ex 
defmodule Constants do 
    @enumerables [List, Map] 
    def enumerables, do: @enumerables 
end 

# reversible.ex 
defprotocol Reversible do 
    def reverse(term) 
end 

for enumerable <- Constants.enumerables do 
    defimpl Reversible, for: enumerable do 
    def reverse(term), do: Enum.reverse(term) 
    end 
end 

テスト:

$ iex -S mix 
iex(1)> Reversible.reverse [1, 2, 3] 
[3, 2, 1] 
iex(2)> Reversible.reverse %{1 => 2, 3 => 4} 
[{3, 4}, {1, 2}] 
+0

は、私は解決策がで再実装 'defimpl'を伴うだろうと思いました何らかの形で引用符で囲まれています。あなたのソリューションはシンプルできれいです、ありがとう! –

関連する問題