2017-12-17 7 views
0

File.lsからファイル/フォルダのリストを取得し、それらにフルパスを追加し、ディレクトリであるかどうかに基づいてフィルタリングするツールを作成しようとしています。か否か。Elixir Enum.mapがEnum.filterにパイプされていません。

これは動作します:

directory_contents = File.ls!(directory_path) 

contents_with_full_paths = Enum.map directory_contents, fn(item) -> Path.join(directory_path, item) end 
only_dirs = Enum.filter contents_with_full_paths, fn(item) -> File.dir?(item) end 

これはしていません:

directory_contents = File.ls!(directory_path) 

directory_contents 
|> Enum.map fn(item) -> Path.join(directory_path, item) end 
|> Enum.filter fn(item) -> File.dir?(item) end 

つまり、なぜそれが

** (Protocol.UndefinedError) protocol Enumerable not implemented for #Function<1.10194857/1 in RepoFinder.subdirectories_in/1>, only anonymous functions of arity 2 are enumerable. This protocol is implemented for: Date.Range, File.Stream, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Range, Stream 
    (elixir) lib/enum.ex:3213: Enumerable.Function.reduce/3 
    (elixir) lib/enum.ex:1847: Enum.filter/2 

を投げますか?これらの2つの実装は、本質的に同じ方法で動作するべきではありませんか?コードがコンパイルされたとき

答えて

4

、コンパイラは、このコードで間違っているものを説明する詳細な警告を投げた:

警告:関数呼び出しに配管する際括弧が必要とされています。 、前記
/path/to/file.ex:line

:例えば:

foo 1 |> bar 2 |> baz 3 

は曖昧であり、で見出さ

foo(1) |> bar(2) |> baz(3) 

あいまいパイプのように記述されるべきですパイプ演算子を使用する場合は、関数呼び出しの引数を括弧で囲むことが必須です。

directory_contents 
|> Enum.map(fn(item) -> Path.join(directory_path, item) end) 
|> Enum.filter(&File.dir?/1) 

それ以外の場合、コンパイラは誤った演算子の優先順位を使用します。

関連する問題