wat-aro
こんな感じのやつ
[1, 2, 3]
|> List.map (\x -> x * 2)
|> List.foldl (+)
|>
の前の値を関数に適用する
以下を満たせば簡単につくれる
第一引数を第二引数に適用するだけ
(|>) :: a -> (a -> b) -> b
(|>) a f = f a
以降の話に関わるのでここでおさらい
複数の引数を受け取る関数を一引数の関数に変換する
uncuffyFunction :: (a, b, c) -> d
uncuffyFunction (a, b, c) = somethingToDo a b c
curriedFunction :: a -> b -> c -> d
curriedFunction a b c = somethingToDo a b c
const uncurryFunction = (a, b, c) => somethigTodo(a, b, c)
const curriedFunction = a => b => c => somethingTodo(a, b, c)
curriedFunctionは引数を一つとると残りの引数を 一つずつ取る関数 を返す
uncurryな関数をcurriedな関数に変換するのが
複数の引数を取る関数で、一部にだけ引数を適用した状態の関数を返す。
const partialApplied = somethigTodo(1, 2, ?)
Elixir などのデフォルトでカリー化されていない言語では関数のようにパイプライン演算子を定義できない
e.g.
ML系は関数の最後の引数に値を差し込む
Elixir は最初の引数を差し込む
[1, [[2], 3]]
|> List.flatten
|> Enum.map(fn x -> x * x end)
|> Enum.reduce(0, fn(x, acc) -> x + acc end)
カリー化されていないためASTを変換する必要がある
パイプラインといいつつただの優先度の低い .
(1..5).map {|x| x * 2 }
1..5 |> map {|x| x * 2 }
のように書ける
これの話をしたかった
"https://api.github.com/repos/ruby/ruby ".:itself
.:
は Ruby 2.7 で入る演算子。
Methodオブジェクトを取り出す。
MethodオブジェクトはほぼProcオブジェクトと同じふるまい。
詳しくはドキュメントを読んでください。
"https://api.github.com/repos/ruby/ruby ".:itself
|>>> URI.:parse
URI.parse
でなく URI.:parse
に注意。
とりだしたMethodオブジェクトを |>
と >>
で合成する。
>>
は Ruby2.6 で入った関数(Proc)合成演算子。
URI.:parse
で URI.parse
のMethodオブジェクトを取りだし、
>>
によって合成している。
つまり
URI.parse("https://api.github.com/repos/ruby/ruby ")
"https://api.github.com/repos/ruby/ruby ".:itself
|>>> URI.:parse
|>>> Net::HTTP.:get
Net::HTTP.:get
で Net:HTTP.get
のMethodオブジェクトを取り出す。
uri = URI.parse("https://api.github.com/repos/ruby/ruby ")
Net::HTTP.get(uri)
"https://api.github.com/repos/ruby/ruby ".:itself
|>>> URI.:parse
|>>> Net::HTTP.:get
|>>> JSON.:parse
ここでも JSON.:parse
で JSON.parse
でMethodオブジェクトを取り出す
uri = URI.parse("https://api.github.com/repos/ruby/ruby ")
response = Net::HTTP.get(uri)
JSON.parse(response)
"https://api.github.com/repos/ruby/ruby ".:itself
|>>> URI.:parse
|>>> Net::HTTP.:get
|>>> JSON.:parse
|> call
今まではMethodオブジェクトを合成しただけなので、ここでやっと評価され、値になる。
"https://api.github.com/repos/ruby/ruby ".:itself
|>>> URI.:parse
|>>> Net::HTTP.:get
|>>> JSON.:parse
|> call
|> fetch("stargazers_count")
Hash#fetch
で値を取りだす
"https://api.github.com/repos/ruby/ruby ".:itself
|>>> URI.:parse
|>>> Net::HTTP.:get
|>>> JSON.:parse
|> call
|> fetch("stargazers_count")
|> then { puts @1 }
そして標準出力へ。
@1
は Ruby2.7で入る予定。
"hoge".then { puts @1 }
"hoge".then {|s| puts s }
たーのしー
パイプライン演算子の説明
Ruby2.7で入る予定のパイプライン演算子とその応用の紹介
関数合成をキメていこう
もっと詳しく知りたい人は