LoginSignup
3

More than 5 years have passed since last update.

関数を引数で渡して、渡した先で関数を走らせる

Posted at

処理の大半は、同一の処理を共有したいけど、一部だけ挙動を変えたい、といったとき、関数を引数で渡すテクニックが、役に立つ

下記の例は、HTTP GETでJSON API結果を拾った後に、list_mapを加工する関数を引数渡しして、加工後を返す例

defmodule Json do
    def get( domain, path, header \\ [], map_function \\ &nop/1 ) do
        domain <> path
        |> HTTPoison.get!( header )
        |> parse( map_function )
    end

    defp parse( response, map_function ) do
        response
        |> get_body
        |> Poison.decode!
        |> map_function.()
    end

    defp get_body( %{ status_code: 200, body: body } ), do: body
    defp nop( map_list ), do: map_list
end

呼び出し側は、こんな感じで、「&」とアリティ付きで指定する(未指定時は、デフォルト引数で無加工の関数が呼ばれる)

defmodule GithubWrapper do
    def run(), do: Json.get( "https://api.github.com", "/rate_limit", &pick_rate/1 )
    defp pick_rate( %{ "rate" => rate } ), do: rate
end

無名関数って、Enum.map()等の高階関数の中で使うケースは多いけど、function.()の形式で使うことは少ないんだが、上記みたいなライブラリ/FW側を作るときには、案外、重宝する

あと、こうしたケースをスマートに書くには、「渡す関数の引数を1個に限定する」という、モナドっぽい考え方がコツ

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3